题目要求:对字符中的各个英文字符(大小写分开统计),数字,空格进行统计,并按照统计个数由多到少输出,如果统计的个数相同,则按照ASII码由小到大排序输出 。如果有其他字符,则对这些字符不用进行统计。如果统计的个数相同,则按照ASII码由小到大排序输出 。如果有其他字符,则对这些字符不用进行统计。实现以下接口: 输入一个字符串,对字符中的各个英文字符,数字,空格进行统计(可反复调用)。按照统计个数由多到少输出统计结果,如果统计的个数相同,则按照ASII码由小到大排序输出清空目前的统计结果,重新统计。调用者会保证:输入的字符串以‘\0’结尾。
代码:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 void statics(char *str) 6 { 7 //char (*ch)[2]; 8 //ch=(char(*)[2])malloc(len); // ch[2][len] 9 int len=strlen(str); 10 char **ch; 11 ch=(char**)malloc(len*sizeof(char*)); 12 for(int i=0;i<len;++i) 13 { 14 ch[i]=(char*)malloc(2*sizeof(char)); // ch[len][2] ,ch[][0]保存字符 ,ch[][1]保存字符出现次数 15 } 16 int i,j,k,n; 17 for(i=0;i<len;++i) 18 ch[i][1]=0; // 初始化ch[][1],以便后面的自增操作 19 for(n=0;n<len;++n) 20 if (str[n]==‘ ‘||(str[n]>=‘0‘&&str[n]<=‘9‘)||(str[n]>=‘a‘&&str[n]<=‘z‘)||(str[n]>=‘A‘&&str[n]<=‘Z‘)) 21 { 22 ch[0][0]=str[n]; // 以字符串中第一个符合条件的字符初始化ch[0][0] 23 ++ch[0][1]; 24 break; 25 } 26 27 i=n+1;k=1; // i从第二个满足条件的字符开始 , k记录ch中保存的字符数 28 while(str[i]!=‘\0‘) // 统计字符串中的字符 29 { 30 char c=str[i]; 31 if (str[i]==‘ ‘||(str[i]>=‘0‘&&str[i]<=‘9‘)||(str[i]>=‘a‘&&str[i]<=‘z‘)||(str[i]>=‘A‘&&str[i]<=‘Z‘)) 32 { 33 for (j=0;j<k;++j) 34 { 35 if (c==ch[j][0]) 36 { 37 ++ch[j][1]; 38 break; 39 } 40 } 41 if (j==k) 42 { 43 ch[j][0]=c; 44 ++ch[j][1]; 45 ++k; 46 } 47 } 48 ++i; 49 } 50 char temp_ch; 51 int temp_int; 52 bool change; 53 for (i=1;i<k;++i) // 采用冒泡排序算法 54 { 55 change=false; 56 for (j=1;j<=k-i;++j) 57 { 58 if (ch[j-1][1]<ch[j][1]) //按照ch[][1]保存的字符个数从大到小排序 59 { 60 temp_ch=ch[j-1][0]; 61 ch[j-1][0]=ch[j][0]; 62 ch[j][0]=temp_ch; 63 temp_int=ch[j-1][1]; 64 ch[j-1][1]=ch[j][1]; 65 ch[j][1]=temp_int; 66 change=true; 67 } 68 if (ch[j-1][1]==ch[j][1]) //如果字符个数相等,按照ch[][0]保存的字符排序,ASII小的在前 69 { 70 if (ch[j-1][0]>ch[j][0]) 71 { 72 temp_ch=ch[j-1][0]; 73 ch[j-1][0]=ch[j][0]; 74 ch[j][0]=temp_ch; 75 temp_int=ch[j-1][1]; 76 ch[j-1][1]=ch[j][1]; 77 ch[j][1]=temp_int; 78 change=true; 79 } 80 } 81 82 } 83 if (!change) 84 { 85 break; 86 } 87 } 88 for(i=0;i<k;++i) // 将结果复制给str 89 { 90 str[i]=ch[i][0]; 91 } 92 str[i]=‘\0‘; 93 94 for (i=0;i<len;++i) 95 { 96 free(ch[i]); 97 } 98 free(ch); 99 100 } 101 102 int main() 103 { 104 int i=0; 105 char str[256],ch; 106 //scanf("%s",str); 107 gets(str); 108 int len=strlen(str); 109 110 statics(str); 111 i=0; 112 while(str[i]!=‘\0‘) 113 { 114 printf("%c",str[i++]); 115 } 116 117 return 0; 118 }
错误总结:
1.如何定义二维数组?
答题过程中,错误地认为下面的代码会定义二维数组ch[len][2],其实,下面的代码定义的二维数组为ch[2][len]。
1 char (*ch)[2]; 2 ch=(char(*)[2])malloc(len); // ch[2][len]
可以使用下面的代码定义ch[len][2]。
1 char **ch; 2 ch=(char**)malloc(len*sizeof(char*)); 3 for(int i=0;i<len;++i) 4 { 5 ch[i]=(char*)malloc(2*sizeof(char)); // ch[len][2] ,ch[][0]保存字符 ,ch[][1]保存字符出现次数 6 }
2.如何输入带空格的字符串?
答题过程中,采用了scanf函数,导致了不能输入含空格的字符串,因为scanf将空格字符作为输入的字符串之间的分割符。
可以采用gets()输入带空格的字符串。
时间: 2024-10-11 08:19:29