一个综合性的C语言字符串编程题目,题目各项要求都是比较经常遇到的各种字符串相关作,感觉像是几个Leetcode题目融合到了一起。
题目介绍:
有字符串s,满足如下要求:
- 字符串s仅允许小写字母、大写字母、数字[0-9]、加号、减号共26+26+10+2=64种符号;
- 加号、减号后继字符只允许数字;
- 从字符串s中取任意连续的字符组成的整数子串,称为s的子整数,如:0, 5, 8, 003, 202, +5, +8, +003, +202, -5, -8, -003, -202;
- 对字符串s,顺次不漏提取一组子整数,构成一个s的一个子整数组合;一个字符串s可以对应多个子整数组合;
编写程序,满足下列功能要求:
- 字符串输入:从键盘输入一个任意长度的字符串;
- 判断合法性:如果字符串不符合上述要求,接受字符串并提示,否则拒绝并提示;
- 字符统计:按照ASCII字符顺序统计字符串字符频次,并显示,未出现的字符不统计;
- 列举字符串的所有的子整数组合,并显示:
- 求解和最小的子整数组合,并显示;
- 按和的升序列举所有的子整数组合,并显示。
代码实现:
#include#include #include int flag; int add = 0; void Init(char s[]) //检查输入 { int i = 1; for(i = 0; i < strlen(s); i ++) { if((s[i] >= 'a' && s[i] <= 'z') || (s[i] == '-') || (s[i] == '+') || (s[i] >= '0' && s[i] <= '9') || (s[i] >= 'A' && s[i] <= 'Z')) { if((s[i] == '-') || (s[i] == '+')) { if(s[i+1] < '0' || s[i+1] > '9') { flag = 0; return ; } } } else { flag = 0; return ; } } return ; } void Count(char s[]) //统计各字母出现频率 { int sum[64] = {0}; //按照ASCII码顺序存储64个字符出现频率 int i; for(i = 0; i < strlen(s); i ++) { if((s[i] == '-') || (s[i] == '+')) { if(s[i] == '+') { sum[0] ++; add ++; } else if(s[i] == '-') { sum[1] ++; add ++; } } else if((s[i] >= '0' && s[i] <= '9')) { int temp = s[i] - 47; sum[1 + temp] ++; } else if((s[i] >= 'A' && s[i] <= 'Z')) { int temp = s[i] - 64; sum[11 + temp] ++; } else if((s[i] >= 'a' && s[i] <= 'z')) { int temp = s[i] - 96; sum[37 + temp] ++; } else { printf("Error!n"); return ; } } printf("The word frequency is as follows:n"); for(i = 0;i < 64; i++) { if(sum[i] != 0) { if(i == 0) { printf(" + : %dn",sum[i]); } else if(i == 1) { printf(" - : %dn",sum[i]); } else if(i >= 2 && i <= 11) { printf(" %d ",i-2); printf(": %dn",sum[i]); } else if(i >= 12 && i <= 37) { char temp; temp = (char)(i+53); printf(" %c : %dn",temp,sum[i]); } else if(i >= 38 && i <= 63) { char temp; temp = (char)(i+59); printf(" %c : %dn",temp,sum[i]); } } } printf("n"); return ; } void Display(char *str[],int number[],int m) //输出所有子整数组合,输出和最大的子整数组合,子整数组合排序并输出 { int min = number[0]; char temp_str[999]; //这里必须设置成char[]类型,char*不行,否则下面strcpy和strcat函数没法用,主要要设置大小,我这里给的999,根据自己需求给 char min_str[999]; //同上,这部分也卡了我挺久的 int temp; char str_sort[999][999]={0}; int sum_add[999]={0}; int sum_sort[999]={0}; int n = 0; strcpy(min_str,str[0]); printf("All combinations are as follows:n"); int i; int j; for(i = 0; i < m;i++) { temp = number[i]; strcpy(temp_str,str[i]); strcpy(str_sort[n],temp_str); sum_add[n] = temp; sum_sort[n] = temp; n++; printf("%sn",temp_str); if(temp < min) { min = temp; strcpy(min_str,temp_str); } for(j = i + 1; j < m;j++) { temp = temp + number[j]; strcat(temp_str,str[j]); strcpy(str_sort[n],temp_str); sum_add[n] = temp; sum_sort[n] = temp; n++; printf("%sn",temp_str); if(temp < min) { min = temp; strcpy(min_str,temp_str); } } } printf("n"); printf("String of minimum sum: "); printf("%sn",min_str); printf("n"); int t; int f[n]; for (j = 0; j < n -1; j++) //根据子整数组合求和大小进行顺序排序 { for (i = 0; i < n-j-1; i++) if (sum_sort[i] > sum_sort[i + 1])//比较 { t = sum_sort[i]; sum_sort[i] = sum_sort[i + 1]; sum_sort[i + 1] = t;//换位 } } printf("Sorted results:n"); for(i = 0;i < n;i++) { for(j = 0;j < n;j++) { if(sum_add[j] == sum_sort[i] && f[j] != 1) { printf("%sn",str_sort[j]); f[j] = 1; } } } return ; } void Extract(char s[]) //拆分输入的字符串,剔除其中的字母字符 { char new_s[strlen(s) + add + 1]; //这块卡了我好久,一开始因为大小未知,就没设置大小,编译器也没报错,但是下面代码运行到下面的语句,寄存器就会错乱 int number[9999] = {0}; char *new_str[9999] = {' '}; int m = 0; int j = 0; int i = 0; memset(new_s, 0 ,sizeof(new_s)); while(i < strlen(s)) //就是这个循环,没设置字符数组大小,变量i给我乱跳,debug了好久都弄不清楚为啥乱跳,最后终于弄明白了,就是上面提到的原因 { if((s[i] < '0' || s[i] > '9') && (s[i] != '-') && (s[i] != '+')) { new_s[j++] = ','; i++; } else if(s[i] == '-' || s[i] == '+') { new_s[j++] = ','; new_s[j++] = s[i++]; } else { new_s[j++] = s[i++]; } } char *token; char *tt; const char c[2] = ","; int value; token = strtok( new_s , c); while(token != NULL) { value = strtol(token,&tt,10); if( tt != token) { number[m] = value; new_str[m] = token; m++; } // if(atoi(token) != 0) // { // number[m] = atoi(token); // new_str[m] = token; // m++; // } token = strtok(NULL,c); } Display(new_str,number,m); return ; } int main() { char s[9999] = {0}; flag = 1; gets(s); Init(s); if(flag == 1) { printf("input success!n"); printf("n"); Count(s); Extract(s); } else if(flag == 0) { printf("Input Error!n"); } else { printf("Error!n"); } system("pause"); return 0; }
总结
在编写过程中由于好久不写C语言,同时不允许调包,走了一些弯路,好在最后算是实现了题目要求。感觉是有一些收获的,对C语言字符串相关操作有了进一步认识。
同时总结了一些C语言字符串相关函数,在我发的另一篇文章,链接附在后面,有兴趣的小伙伴可以看一眼。
C语言字符串常用函数总结(持续更新)_文刀宝宝的博客-CSDN博客



