66 字符串统计

作者: SunCiHai时间限制: 10S章节: 字符串

问题描述 :

明明最近在做一个有关字符串的统计工作。两个由小写字母组成的字符串s1和s2,明明需要统计出以下四种关系:

(1)在s1或s2中存在的字母(包括在s1和s2中都存在的字母);

(2)在s1中且在s2中的字母;

(3)在s1中但不在s2中的字母,在s2中但不在s1中的字母;

(4)不在s1中且也不在s2中的字母;

例如两个字符串s1为“lkjsvoahs”,s2为“qglhskjdfg”:

(1)在s1或者在s2或者s1、s2中都存在的字母:adfghjkloqsv;

(2)在s1中且在s2中的字母:hjkls;

(3)在s1中但不在s2中的字母,在s2中但不在s1中的字母:adfgoqv;

(4)不在s1中且也不在s2中的字母:bceimnprtuwxyz;

明明统计了很久,但是由于统计过程十分繁琐,且很容易出错,导致明明的进度非常慢,很有可能因为统计不完而错过了晚上的约会。因此明明想请你帮个忙,帮他写一个程序,用程序来统计出以上几项内容。

明明的问题可以归结为:

输入两串由小写字母组成的字符串s1和s2,比较其中的字母,输出以下四项,输出的字母以字典顺序排列:

(1)在s1或s2中存在的字母(包括在s1和s2中都存在的字母);

(2)在s1中且在s2中的字母;

(3)在s1中但不在s2中的字母,在s2中但不在s1中的字母;

(4)不在s1中且也不在s2中的字母;

例如字符串s1为sadf,s2为asdf,则需输出以下四行(注意输出的格式):

in s1 or s2:adfs

in s1 and s2:adfs

in s1 but not in s2 ,or in s2 but not in s1:

not in s1 and s2:bceghijklmnopqrtuvwxyz

输入说明 :

你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。标准输入设备中有多组测试数据,每组测试数据两行,每组测试数据的第一行为字符串s1,每组测试数据的第二行为字符串s2;s1和s2都由小写英文字母组成,且长度不超过26个字符。测试数据与其后一组测试数据之间没有任何空行,第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。
输出说明 :

对于每一组测试数据,你写的程序要求计算出一组相应的运算结果,并将这一组运算结果作为你所写程序的输出数据依次写入到标准输出设备中。

每组运算结果由四行组成:

第一行为在s1或者在s2或者s1、s2中都存在的字母;

第二行为在s1中且在s2中的字母;

第三行为在s1中但不在s2中的字母,在s2中但不在s1中的字母;

第四行为不在s1中且也不在s2中的字母;

具体格式请参考样例输出。

每组运算结果其行首和行尾都没有任何空格,每组运算结果与其后一组运算结果之间有一个空行,最后一组运算结果后面没有空行。

注:通常,显示屏为标准输出设备。 输入范例 : sadf asdf lkjsvoahs qglhskjdfg 输出范例 : in
s1 or s2:adfs in s1 and s2:adfs in s1 but not in s2 ,or in s2 but not
in s1: not in s1 and s2:bceghijklmnopqrtuvwxyz

in s1 or s2:adfghjkloqsv in s1 and s2:hjkls in s1 but not in s2 ,or in
s2 but not in s1:adfgoqv not in s1 and s2:bceimnprtuwxyz

原来的代码:

/*T66 字符串统计 第一种情况:即两字符串的并集。将两字符串连接起来后排序,再去重 第二种情况:即两字符串的交集。将两字符串分别去重,排序,再取前一段相同字符 第三种情况:str1去掉二者交集与str2去掉二者交集的并集也就是在第一种情况中去掉第二种情况 第四种情况:即在全部26个字母中抠掉第一种情况。
*/ #include<stdio.h>
#include<string.h>
#define MAX_SIZE 27void sortByAlphabet(char str[]);
void removeDupl(char str[]); int main() {char str1[MAX_SIZE] = "";char str2[MAX_SIZE] = "";char res[MAX_SIZE] = "";// 每种情况的结果 char resTemp[MAX_SIZE] = "";char temp1[MAX_SIZE] = "";char temp2[MAX_SIZE] = "";int count = 0;int i = 0, j = 0, k = 0;int len1 = 0, len2 = 0, len = 0;int flag = 0;char characters[26] = "";while (scanf("%s", str1) != EOF) {scanf("%s", str2);// 注意输出还要加点东西 for (i = 0; i < 26; i++) {characters[i] = 'a' + i;}characters[26] = '\0';len1 = strlen(str1);len2 = strlen(str2);strcpy(temp1, str1);strcpy(temp2, str2);// 第一种 strcpy(res, strcat(str1, str2));// 连接sortByAlphabet(res);// 排序removeDupl(res);// 去重printf("in s1 or s2:%s\n", res);for (i = 0; i < strlen(res); i++)resTemp[i] = res[i];resTemp[i] = '\0';printf("resTemp=%s\n", resTemp);strcpy(resTemp, res);// 将res存下来 ******************************************    // 这里怎么会有问题???? // 第二种 flag = 0;for (i = 0; i < len1; i++) {for (j = 0; j < len2; j++) {if (temp1[i] == temp2[j]) {// 有相同字符 flag = 1;break;}}}if (flag) {removeDupl(temp1);removeDupl(temp2);sortByAlphabet(temp1);sortByAlphabet(temp2);i = len1 <= len2 ? len1 : len2;temp1[i] = '\0'; printf("in s1 and s2:%s\n", temp1);} else {temp1[0] = '\0';printf("in s1 and s2:\n");} // 第三种 if (strlen(temp1) == 0) {// 两字符串没有交集,则就是第一种情况 printf("in s1 but not in s2 ,or in s2 but not in s1:%s\n", resTemp);}else {len = strlen(resTemp);for (i = 0; i < strlen(resTemp); i++) {for (j = 0; j < strlen(temp1); j++) {if (resTemp[i] == temp1[j]) {// 将相同元素删除 for (k = i; k < len - 1; k++) {resTemp[k] = resTemp[k + 1];}resTemp[len - 1] = '\0';len--;}}}printf("in s1 but not in s2 ,or in s2 but not in s1:%s\n", resTemp);}// 第四种len = strlen(characters);for (i = 0; i < len; i++) {for (j = 0; j < strlen(res); j++) {if (characters[i] == res[j]) {// 将相同元素删除 for (k = i; k < len - 1; k++) {characters[k] = characters[k + 1];}characters[len - 1] = '\0';//   printf("%s\n", characters);len--;}}}printf("not in s1 and s2:%s\n", characters); // 怎么到最后还有个adfs????? }return 0;
} // 按字典顺序对字符串进行排序
void sortByAlphabet(char str[]) {int i = 0, j = 0;char ch = 'a';int len = strlen(str);for (i = len - 1; i > 0; i--) {for (j = 0; j < i; j++) {if (str[j] - 'a' > str[j + 1] - 'a') {ch = str[j];str[j] = str[j + 1];str[j + 1] = ch;}}}
} // 字符串去重
void removeDupl(char str[]) {char res[MAX_SIZE] = "";int i = 0, j = 0;int len =  strlen(str);for (i = 0; i < len - 1; i++) {if (str[i] != str[i + 1]) {res[j++] = str[i];}}if (res[j - 1] != str[len - 1]) {// 检查后面是否有相同字符 res[j] = str[len - 1];j++; }res[j] = '\0';strcpy(str, res);
}

唉,我也不晓得它是什么鬼,看起来明明没问题,最后总要加个尾巴……
参考了大佬的代码,把原来的四个模块换成了四个函数,经过修改后的代码:

/*T66 字符串统计 第一种情况:即两字符串的并集。将两字符串连接起来后排序,再去重 第二种情况:即两字符串的交集。将两字符串分别去重,排序,再取前一段相同字符 第三种情况:str1去掉二者交集与str2去掉二者交集的并集也就是在第一种情况中去掉第二种情况 第四种情况:即在全部26个字母中抠掉第一种情况。
*/ #include<stdio.h>
#include<string.h>
#define MAX_SIZE 27void sortByAlphabet(char str[]);
void removeDupl(char str[]);
void case1(char str1[], char str2[]);
void case2(char str1[], char str2[]);
void case3(char str1[], char str2[]);
void case4(char str1[], char str2[]);int main() {char str1[MAX_SIZE] = "";char str2[MAX_SIZE] = "";
//  char str1[MAX_SIZE] = "sadf";
//  char str2[MAX_SIZE] = "asdf";
//  char str1[MAX_SIZE] = "lkjsvoahs";
//  char str2[MAX_SIZE] = "qglhskjdfg";char temp1[MAX_SIZE] = "";char temp2[MAX_SIZE] = "";int count = 0;while (scanf("%s", str1) != EOF) {scanf("%s", str2);if (++count != 1) {printf("\n");}strcpy(temp1, str1);strcpy(temp2, str2);case1(temp1, temp2); strcpy(temp1, str1);strcpy(temp2, str2);case2(temp1, temp2);strcpy(temp1, str1);strcpy(temp2, str2); case3(temp1, temp2); strcpy(temp1, str1);strcpy(temp2, str2);case4(temp1, temp2); }return 0;
} // 按字典顺序对字符串进行排序
void sortByAlphabet(char str[]) {int i = 0, j = 0;char ch = 'a';int len = strlen(str);for (i = len - 1; i > 0; i--) {for (j = 0; j < i; j++) {if (str[j] - 'a' > str[j + 1] - 'a') {ch = str[j];str[j] = str[j + 1];str[j + 1] = ch;}}}
} // 字符串去重
void removeDupl(char str[]) {char res[MAX_SIZE] = "";int i = 0, j = 0;int len =  strlen(str);for (i = 0; i < len - 1; i++) {if (str[i] != str[i + 1]) {res[j++] = str[i];}}if (res[j - 1] != str[len - 1]) {// 检查后面是否有相同字符 res[j] = str[len - 1];j++; }res[j] = '\0';strcpy(str, res);
} // 第一种情况      没问题
void case1(char str1[], char str2[]) {char res[MAX_SIZE] = "";strcpy(res, strcat(str1, str2));// 连接sortByAlphabet(res);// 排序removeDupl(res);// 去重printf("in s1 or s2:%s\n", res);
}// 第二种情况       没问题了
void case2(char str1[], char str2[]) {int len1 = strlen(str1);int len2 = strlen(str2);char res[MAX_SIZE] = "";int count = 0;// 公共字符计数 int i = 0, j = 0;removeDupl(str1);// 去重 for (i = 0; i < len1; i++) {for (j = 0; j < len2; j++) {if (str1[i] == str2[j]) {// 相同字符 res[count++] = str1[i];}}}res[count] = '\0'; sortByAlphabet(res);// 排序 removeDupl(res);// 去重 printf("in s1 and s2:%s\n", res);
}// 第三种情况       没问题了
void case3(char str1[], char str2[]) { char res1[MAX_SIZE] = "";char res2[MAX_SIZE] = "";int len = 0;int i = 0, j = 0, k = 0;int len1 = strlen(str1);int len2 = strlen(str2);int count = 0;// 公共字符计数 // 重复第一种情况 strcpy(res1, strcat(str1, str2));// 连接sortByAlphabet(res1);// 排序removeDupl(res1);// 去重// 重复第二种情况removeDupl(str1);// 去重 for (i = 0; i < len1; i++) {for (j = 0; j < len2; j++) {if (str1[i] == str2[j]) {// 相同字符 res2[count++] = str1[i];}}}res2[count] = '\0'; sortByAlphabet(res2);// 排序 removeDupl(res2);// 去重 if (strlen(res2) == 0) {// 两字符串没有交集,则就是第一种情况 printf("in s1 but not in s2 ,or in s2 but not in s1:%s\n", res1);}else {// 在第一种情况里面抠掉第二种情况 len = strlen(res1);for (i = 0; i < strlen(res1); i++) {for (j = 0; j < strlen(res2); j++) {if (res1[i] == res2[j]) {// 将相同元素删除 for (k = i; k < len - 1; k++) {res1[k] = res1[k + 1];}res1[len - 1] = '\0';len--;}}}printf("in s1 but not in s2 ,or in s2 but not in s1:%s\n", res1);}
}// 第四种情况       没问题
void case4(char str1[], char str2[]) {char characters[26] = "abcdefghijklmnopqrstvuwxyz";char res[MAX_SIZE] = "";int i = 0, j = 0, k = 0;int len = 0;strcpy(res, strcat(str1, str2));// 连接sortByAlphabet(res);// 排序removeDupl(res);// 去重len = strlen(characters);for (i = 0; i < len; i++) {for (j = 0; j < strlen(res); j++) {if (characters[i] == res[j]) {// 将相同元素删除 for (k = i; k < len - 1; k++) {characters[k] = characters[k + 1];}characters[len - 1] = '\0';// printf("%s\n", characters);len--;}}}printf("not in s1 and s2:%s\n", characters);
}

运行之后没问题了,可是到了oj出现这种情况:


我无语了,不晓得是oj错了还是我错了……先放着吧,明天再查下

DIY分割线++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++DIY分割线

今天我打算把四个函数里面的所有内容重写一遍,不用之前杂糅的方法,每种情况的结果独立,不参与其他情况的求解
改了一通,调了一通,总算AC了……

/*T66 字符串统计 第一种情况:即两字符串的并集。将两字符串连接起来后排序,再去重 第二种情况:即两字符串的交集。将两字符串分别去重,排序,再取前一段相同字符 第三种情况:str1去掉二者交集与str2去掉二者交集的并集也就是在第一种情况中去掉第二种情况 第四种情况:即在全部26个字母中抠掉第一种情况。
*/ #include<stdio.h>
#include<string.h>
#define MAX_SIZE 27void sortByAlphabet(char str[]);
void removeDupl(char str[]);
void case1(char str1[], char str2[]);
void case2(char str1[], char str2[]);
void case3(char str1[], char str2[]);
void case4(char str1[], char str2[]);int main() {char str1[MAX_SIZE] = "";char str2[MAX_SIZE] = "";
//  char str1[MAX_SIZE] = "qwekljdfvoj";
//  char str2[MAX_SIZE] = "eriiigjigowjegojw";
//  char str1[MAX_SIZE] = "lkjsvoahs";
//  char str2[MAX_SIZE] = "qglhskjdfg";char temp1[MAX_SIZE] = "";char temp2[MAX_SIZE] = "";int count = 0;while (scanf("%s", str1) != EOF) {scanf("%s", str2);if (++count != 1) {printf("\n");}strcpy(temp1, str1);strcpy(temp2, str2);case1(temp1, temp2); strcpy(temp1, str1);strcpy(temp2, str2);case2(temp1, temp2);strcpy(temp1, str1);strcpy(temp2, str2); case3(temp1, temp2); strcpy(temp1, str1);strcpy(temp2, str2);case4(temp1, temp2); }return 0;
} // 按字典顺序对字符串进行排序
void sortByAlphabet(char str[]) {int i = 0, j = 0;char ch = 'a';int len = strlen(str);for (i = len - 1; i > 0; i--) {for (j = 0; j < i; j++) {if (str[j] - 'a' > str[j + 1] - 'a') {ch = str[j];str[j] = str[j + 1];str[j + 1] = ch;}}}
} // 字符串去重(建立在字符串有序的基础上)
void removeDupl(char str[]) {char res[MAX_SIZE] = "";int i = 0, j = 0;int len =  strlen(str);for (i = 0; i < len - 1; i++) {if (str[i] != str[i + 1]) {res[j++] = str[i];}}if (res[j - 1] != str[len - 1]) {// 检查后面是否有相同字符 res[j] = str[len - 1];j++; }res[j] = '\0';strcpy(str, res);
} // 第一种情况
void case1(char str1[], char str2[]) {char res[MAX_SIZE] = "";int i = 0, j = 0;int len = 0;int flag = 0; sortByAlphabet(str1);// 排序 sortByAlphabet(str2);removeDupl(str1);// 去重 removeDupl(str2);strcpy(res, str1);len = strlen(res);for (i = 0; i < strlen(str2); i++) {flag = 0;for (j = 0; j < strlen(str1); j++) {if (str2[i] == str1[j]) flag = 1;}if (!flag) {res[len++] = str2[i];}}res[len] = '\0';sortByAlphabet(res);printf("in s1 or s2:%s\n", res);
}// 第二种情况
void case2(char str1[], char str2[]) {char res[MAX_SIZE] = "";int i = 0, j = 0;int count = 0;int flag = 0;for (i = 0; i < strlen(str1); i++) {for (j = 0; j < strlen(str2); j++) {if (str1[i] == str2[j]) {flag = 1;res[count++] = str1[i];}}}if (!flag) {// 没有相同元素 printf("in s1 and s2:\n");return ; }res[count] = '\0';sortByAlphabet(res);// 先排序removeDupl(res);// 再去重 printf("in s1 and s2:%s\n", res);
}// 第三种情况
void case3(char str1[], char str2[]) { char res[MAX_SIZE] = "";int i = 0, j = 0;int count = 0;int flag = 0;for (i = 0; i < strlen(str1); i++) {// 在s1中但是不在s2中 flag = 0;for (j = 0; j < strlen(str2); j++) {if (str1[i] == str2[j]) {flag = 1;}}if (!flag) {res[count++] = str1[i];}} for (i = 0; i < strlen(str2); i++) {// 在s2中但是不在s1中 flag = 0;for (j = 0; j < strlen(str1); j++) {if (str2[i] == str1[j]) {flag = 1;}}if (!flag) {res[count++] = str2[i];}}if (count == 0) {// 没有满足条件的元素 printf("in s1 but not in s2 ,or in s2 but not in s1:\n");return ;  }res[count] = '\0'; sortByAlphabet(res);// 先排序removeDupl(res);// 再去重 printf("in s1 but not in s2 ,or in s2 but not in s1:%s\n", res);
}// 第四种情况
void case4(char str1[], char str2[]) {char characters[MAX_SIZE] = "abcdefghijklmnopqrstvuwxyz";char res[MAX_SIZE] = "";int count = 0;int i = 0, j = 0;int flag = 0;for (i = 0; i < strlen(characters); i++) {flag = 0;for (j = 0; j < strlen(str1); j++) {// 检查当前字符是否在s1中 if (characters[i] == str1[j])flag = 1; }if (flag == 1)continue;for (j = 0; j < strlen(str2); j++) {// 检查当前字符是否在s2中 if (characters[i] == str2[j])flag = 1; }if (!flag) {res[count++] = characters[i];}}res[count] = '\0';sortByAlphabet(res);// 先排序removeDupl(res);// 再去重 printf("not in s1 and s2:%s\n", res);
}


我太菜了……以后不搞那么多花里胡哨的了。

东华oj-进阶题第66题-字符串统计相关推荐

  1. 东华OJ进阶题47 最少拦截系统

    47 最少拦截系统 作者: xxx时间限制: 1S章节: 一维数组 问题描述 : 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高 ...

  2. 【东华oj】基础/进阶刷题

    东华oj 前言 基础题 [顺序结构] 1 求长方形的面积和周长 2 数列和 3 解方程 [分支结构] 4 一个月的天数 5 银行存款到期日 6 实数运算 7 解二次方程 8 门票价格计算 9 星期几问 ...

  3. 进阶题66 字符串统计

    66 字符串统计 作者: SunCiHai时间限制: 10S章节: 字符串 问题描述 : 明明最近在做一个有关字符串的统计工作.两个由小写字母组成的字符串s1和s2,明明需要统计出以下四种关系: (1 ...

  4. POJ C++程序设计 编程题#7:字符串排序

    编程题#7:字符串排序 来源: 北京大学在线程序评测系统POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 总时间限制: 1000ms 内存限制: 1024k ...

  5. DSt:数据结构的最强学习路线之数据结构知识讲解与刷题平台、刷题集合、问题为导向的十大类刷题算法(数组和字符串、栈和队列、二叉树、堆实现、图、哈希表、排序和搜索、动态规划/回溯法/递归/贪心/分治)总

    DSt:数据结构的最强学习路线之数据结构知识讲解与刷题平台.刷题集合.问题为导向的十大类刷题算法(数组和字符串.栈和队列.二叉树.堆实现.图.哈希表.排序和搜索.动态规划/回溯法/递归/贪心/分治)总 ...

  6. 北邮oj题库刷题计划(更新ing)

    北邮oj题库刷题计划(更新ing) 83. A + B Problem 84 Single Number 85. Three Points On A Line 120 日期 121 最值问题 122 ...

  7. 剑指Offer 66题 python版本 汇总

    牛客网剑指offer 66题汇总 (python) 有部分参考牛客网答案,部分为自己提交结果 1. 二维数组中的查找 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每 ...

  8. [Leedcode][JAVA][第680题][验证回文字符串Ⅱ][贪心][递归]

    [问题描述][第680题][验证回文字符串Ⅱ][简单] 给定一个非空字符串 s,最多删除一个字符.判断是否能成为回文字符串.示例 1:输入: "aba" 输出: True 示例 2 ...

  9. python第六章函数课后答案_浙大PTA-Python题库 函数题(6-1~6-6)题解

    其他各章题解链接如下 浙大PTA-Python题库 编程题第一章(1-1~1-3)题解 https://blog.csdn.net/zimuzi2019/article/details/1070206 ...

最新文章

  1. 深度丨吴恩达走了,林元庆也走了,百度研究院到底怎么了?
  2. JSR349(Bean Validation 1.1)
  3. es6 匿名函数求阶乘
  4. OpenCV C++ 07 - Histogram Equalization of a Color image with OpenCV
  5. c++语言中如果调用函数时,需要改变实参或者返回多个值,应该采取,2013年计算机二级C++模拟试题十一及答案...
  6. 黑马程序员-------------(十)Java基础知识加强(一)
  7. python redis pipeline使用方法_python使用pipeline批量读写redis的方法
  8. java中使用正则匹配所有标点符号
  9. 零基础学python实战-Python3零基础入门到爬虫实战
  10. python新手小项目实例-有没有简单一点的 Python 小例子或小项目?
  11. 华为实习日记——第三十七天
  12. pytorch基础API介绍
  13. rect函数_Python基础进阶:从函数到高级魔法方法--Day 6
  14. python建模预测_如何使用Python进行节目观众数的线性回归预测
  15. linux内核容器的打包,简年6:一个关于 Linux 容器化的脑洞
  16. 飞猪IP-代理-换IP作用
  17. 清理 Chrome DNS Cache
  18. C# 生成word文件 小学一年级口算题生成器(代码)
  19. 阿里云禁止root用户直接登录的解决办法
  20. 【学习记录】Tpro遥控器_暂时取消Tpro的控制权(简易)

热门文章

  1. linux查看根目录所有磁盘空间,linux查看磁盘空间及处理方法
  2. 漏洞扫描工具openvas
  3. 你想要的宏基因组-微生物组知识全在这(2023.5)
  4. TreeMap源码解析。
  5. 【Windows】 Win10下报错:该文件没有与之关联的应用来执行该操作。请安装应用,若已经安装应用,请在“默认应用设置”页面中创建关联
  6. 应用系统部署注意事项
  7. React 中 Context 和 contextType的使用
  8. 实例分析join、left join、right join、fulljoin间的区别
  9. 天龙八部TLBB从0到1搭建教程-上
  10. 【tensorflow】多维张量做tf.matmul