11
回答
C语言:输入一串字符,以‘?’结束,统计各字母出现的次数,并按字母出现的多少输出
注册华为云得mate10,2.9折抢先购!>>>   

有一个C语言的题目,题目如下

/*  15、输入一串字符,以‘?’结束,统计各字母出现的次数,并按字母出现的多少输出
(先输出字母出现多的,次数相同的按字母表顺序输出,不出现的字母不输出)。
  例:输入:5b3a+4-hdeh5dh?
      输出:   h    3
               d    2
               a    1
               b    1
               e    1
*/

先说下我自己的思路,我自己的思路是定义一个数组放字符,再定义一个数组a[26]放字母。再定义一个数组b[26]放字母出现的次数,a,b两个数组是对应的。在排序的时候,交换b数组的时候也交换a数组。然后再输出。

最后的结果是什么都没有输出,我尝试着调试了一下,但是代码太长,很难看出问题。

我自己都觉得我的算法实在是太复杂了,代码也写了很长,所以就不贴上来了。

//下面是我在网上查的代码


int cnt[52]={0};
	 char ch;
	 int i;
	 do
	 {  
	  scanf("%c",&ch);
	  if(ch>'A' && ch<'Z') cnt[ch-'A']++;
	  if(ch>'a' && ch<'z') cnt[26+ch-'a']++;  
	 }while(ch!='?');
	 for(i=0;i<26;i++)
	 {	
		 printf("%c     %d\n",'A'+i,cnt[i]);
	 }

	 for(i=0;i<26;i++)
	 {
		 printf("%c     %d\n",'a'+i,cnt[26+i]);
	 }




网上的这段代码其实很好,但是它没有按照题目要求给字母排序,还有就是没有出现的字母是不需要打印的。

我尝试着改了一下,但是效果不好,希望大神能给解答一下。


下面是按照建立一个结构体所写的代码,但是代码出错。

#define  N  1024
void f12()
{
	//输入一串字符以?结束
	char str[N];
	int i;
	for(i=0;str[i]!='?';i++)
	{
		scanf("%c",str[i]);
	}
	//最后一个字符赋值为?
	str[i]='?';	
	//全部字母小写化
	for(i=0;str[i]!='?';i++)
	{
		str[i]=tolower(str[i]);
	}

	//定义一个结构体来记录字符和次数
	Info a[26];
	for(i=0;i<26;i++)
	{
		a[i].letter=i+97;
		a[i].count=0;
	}
	//统计字符
	for(i=0;str[i]!='?';i++)
	{
		if(str[i]>='a'&&str[i]<='z')
		{
			a[str[i]-'a'].count++;
		}
	}

	//排序
	int j;
	for(i=0;i<26;i++)
	{
		int k=i;
		for(j=0;j<25;j++)
		{
			if(a[j].count>a[j+1].count)	
			{
				//交换
				int t=a[j].count;
				a[j].count=a[j+1].count;
				a[j+1].count=t;

				char c = a[j].letter;
				a[j].letter=a[j+1].letter;
				a[j+1].letter=c;
			}
		}
	}
	//输出
	for(i=0;i<26;i++)
	{
		printf("%c     %d\n",a[i].letter,a[i].count);
	}
}




c
举报
水晶之夜
发帖于4年前 11回/8K+阅
共有11个答案 最后回答: 4年前

链表啊,结构体里放一个char来记录字母,一个int来计数,遍历字符串后排序输出。

--- 共有 2 条评论 ---
水晶之夜谢谢额 我猜自己发现了错误,又改写了一下,现在已经成功了。 4年前 回复
水晶之夜我尝试去这样做了,但是结果还是出错。有思路,但是还是比较复杂,代码写出来了出错。也不知道是哪里有问题. 4年前 回复
定义个数组c=int[26][2],c[0][0]='a',c[0][1]=次数,然后排序,然后输出,如果次数为0,则不输出,选个排序算法就行了
--- 共有 2 条评论 ---
NealFeng回复 @水晶之夜 : 输出的时候类型强制转换下,(char)c[0][0]。估计用指针数组也行,或者也可以用typedef定义一个struct,但这些具体怎么写语句我也不会,没怎么好好用过C,反正大体上应该是这么个意思。 4年前 回复
水晶之夜这里有一个问题,你定义的数组是整形的还是字符型?你不可能一个放字符,一个放次数,它们是不同的数据类型。 4年前 回复

引用来自“猎户座”的答案

链表啊,结构体里放一个char来记录字母,一个int来计数,遍历字符串后排序输出。

我自己又重新调试了一下,把代码稍稍改了一下。现在基本上可以了。

#define  N  1024
void f12()
{
	//输入一串字符以?结束
	char str[N];
	gets(str);
	//全部字母小写化
	int i;
	for(i=0;str[i]!='\0';i++)
	{
		str[i]=tolower(str[i]);
	}

	//定义一个结构体来记录字符和次数
	Info a[26];
	for(i=0;i<26;i++)
	{
		a[i].letter=i+97;
		a[i].count=0;
	}
	//统计字符
	for(i=0;str[i]!='\0';i++)
	{
		if(str[i]>='a'&&str[i]<='z')
		{
			a[str[i]-'a'].count++;
		}
	}

	//排序
	int j;
	for(i=0;i<26;i++)
	{
		int k=i;
		for(j=0;j<25;j++)
		{
			if(a[j].count<a[j+1].count)	
			{
				//交换
				int t=a[j].count;
				a[j].count=a[j+1].count;
				a[j+1].count=t;

				char c = a[j].letter;
				a[j].letter=a[j+1].letter;
				a[j+1].letter=c;
			}
		}
	}
	//输出
	for(i=0;i<26;i++)
	{
		if(a[i].count==0) continue;
		printf("%c     %d\n",a[i].letter,a[i].count);
	}
}



引用来自“NealFeng”的答案

定义个数组c=int[26][2],c[0][0]='a',c[0][1]=次数,然后排序,然后输出,如果次数为0,则不输出,选个排序算法就行了

哈,你这个貌似多做事情了。题目是针对字母,没针对其他分类方法。那么就可以直接

int alpha[26];

void init_alpha(void){
     int i; 
     for (i = 0 ; i < 26 ; i ++ ) alpha[i] = 0;
}
#define _CHK_SET(a,min,max) do {if((a >= (min))&&(a <= (max))){alpha[a-min] += 1;}while (0)
void set_alpha(char a){
     _CHK_SET(a ,'A','Z');
     _CHK_SET(a,'a','z');
}
int max_num(void){
    int re = alpha[0];
    int i;
    for (i = 1 ; i< 26 ; i++) {
         if (alpha[i] > re) re = alpha[i];
    }
    return re;
}
int print_max(void){
   int i;
   int flag = 0;
   i = max_num();
   if (alpha[i] == 0){
       return 0;
   }
   printf(....);
   alpha[i] = 0;
   return 1;
}



余下,就是初始化。然后读一个字符如果不是结束符,就掉用一次set_alpha,全部处理完就不停的调用print_max 直到返回为0.

哈, 原型设计不要考虑优化问题。逻辑清楚是关键。有什么好排序的。你排序的价值在于降低不必要的逻辑处理,但和目标逻辑没有关系。



--- 共有 1 条评论 ---
猎户座有一点挺有意思的,确实,要求是打印出来,干嘛排序呢? 4年前 回复

引用来自“中山野鬼”的答案

引用来自“NealFeng”的答案

定义个数组c=int[26][2],c[0][0]='a',c[0][1]=次数,然后排序,然后输出,如果次数为0,则不输出,选个排序算法就行了

哈,你这个貌似多做事情了。题目是针对字母,没针对其他分类方法。那么就可以直接

int alpha[26];

void init_alpha(void){
     int i; 
     for (i = 0 ; i < 26 ; i ++ ) alpha[i] = 0;
}
#define _CHK_SET(a,min,max) do {if((a >= (min))&&(a <= (max))){alpha[a-min] += 1;}while (0)
void set_alpha(char a){
     _CHK_SET(a ,'A','Z');
     _CHK_SET(a,'a','z');
}
int max_num(void){
    int re = alpha[0];
    int i;
    for (i = 1 ; i< 26 ; i++) {
         if (alpha[i] > re) re = alpha[i];
    }
    return re;
}
int print_max(void){
   int i;
   int flag = 0;
   i = max_num();
   if (alpha[i] == 0){
       return 0;
   }
   printf(....);
   alpha[i] = 0;
   return 1;
}



余下,就是初始化。然后读一个字符如果不是结束符,就掉用一次set_alpha,全部处理完就不停的调用print_max 直到返回为0.

哈, 原型设计不要考虑优化问题。逻辑清楚是关键。有什么好排序的。你排序的价值在于降低不必要的逻辑处理,但和目标逻辑没有关系。



我测试了你一下你这个代码,还有5个错误。不太理解。。

--------------------Configuration: temp - Win32 Debug--------------------
Compiling...
temp.cpp
d:\my files\c program\wow\temp\temp.cpp(25) : error C2062: type 'int' unexpected
d:\my files\c program\wow\temp\temp.cpp(26) : error C2143: syntax error : missing ';' before '{'
d:\my files\c program\wow\temp\temp.cpp(33) : error C2562: 'set_alpha' : 'void' function returning a value
        d:\my files\c program\wow\temp\temp.cpp(21) : see declaration of 'set_alpha'
d:\my files\c program\wow\temp\temp.cpp(35) : error C2601: 'print_max' : local function definitions are illegal
d:\my files\c program\wow\temp\temp.cpp(46) : fatal error C1004: unexpected end of file found
Error executing cl.exe.

temp.obj - 5 error(s), 0 warning(s)



引用来自“中山野鬼”的答案

引用来自“NealFeng”的答案

定义个数组c=int[26][2],c[0][0]='a',c[0][1]=次数,然后排序,然后输出,如果次数为0,则不输出,选个排序算法就行了

哈,你这个貌似多做事情了。题目是针对字母,没针对其他分类方法。那么就可以直接

int alpha[26];

void init_alpha(void){
     int i; 
     for (i = 0 ; i < 26 ; i ++ ) alpha[i] = 0;
}
#define _CHK_SET(a,min,max) do {if((a >= (min))&&(a <= (max))){alpha[a-min] += 1;}while (0)
void set_alpha(char a){
     _CHK_SET(a ,'A','Z');
     _CHK_SET(a,'a','z');
}
int max_num(void){
    int re = alpha[0];
    int i;
    for (i = 1 ; i< 26 ; i++) {
         if (alpha[i] > re) re = alpha[i];
    }
    return re;
}
int print_max(void){
   int i;
   int flag = 0;
   i = max_num();
   if (alpha[i] == 0){
       return 0;
   }
   printf(....);
   alpha[i] = 0;
   return 1;
}



余下,就是初始化。然后读一个字符如果不是结束符,就掉用一次set_alpha,全部处理完就不停的调用print_max 直到返回为0.

哈, 原型设计不要考虑优化问题。逻辑清楚是关键。有什么好排序的。你排序的价值在于降低不必要的逻辑处理,但和目标逻辑没有关系。



简洁、明了

引用来自“水晶之夜”的答案

引用来自“中山野鬼”的答案

引用来自“NealFeng”的答案

定义个数组c=int[26][2],c[0][0]='a',c[0][1]=次数,然后排序,然后输出,如果次数为0,则不输出,选个排序算法就行了

哈,你这个貌似多做事情了。题目是针对字母,没针对其他分类方法。那么就可以直接

int alpha[26];

void init_alpha(void){
     int i; 
     for (i = 0 ; i < 26 ; i ++ ) alpha[i] = 0;
}
#define _CHK_SET(a,min,max) do {if((a >= (min))&&(a <= (max))){alpha[a-min] += 1;}while (0)
void set_alpha(char a){
     _CHK_SET(a ,'A','Z');
     _CHK_SET(a,'a','z');
}
int max_num(void){
    int re = alpha[0];
    int i;
    for (i = 1 ; i< 26 ; i++) {
         if (alpha[i] > re) re = alpha[i];
    }
    return re;
}
int print_max(void){
   int i;
   int flag = 0;
   i = max_num();
   if (alpha[i] == 0){
       return 0;
   }
   printf(....);
   alpha[i] = 0;
   return 1;
}



余下,就是初始化。然后读一个字符如果不是结束符,就掉用一次set_alpha,全部处理完就不停的调用print_max 直到返回为0.

哈, 原型设计不要考虑优化问题。逻辑清楚是关键。有什么好排序的。你排序的价值在于降低不必要的逻辑处理,但和目标逻辑没有关系。



我测试了你一下你这个代码,还有5个错误。不太理解。。

--------------------Configuration: temp - Win32 Debug--------------------
Compiling...
temp.cpp
d:\my files\c program\wow\temp\temp.cpp(25) : error C2062: type 'int' unexpected
d:\my files\c program\wow\temp\temp.cpp(26) : error C2143: syntax error : missing ';' before '{'
d:\my files\c program\wow\temp\temp.cpp(33) : error C2562: 'set_alpha' : 'void' function returning a value
        d:\my files\c program\wow\temp\temp.cpp(21) : see declaration of 'set_alpha'
d:\my files\c program\wow\temp\temp.cpp(35) : error C2601: 'print_max' : local function definitions are illegal
d:\my files\c program\wow\temp\temp.cpp(46) : fatal error C1004: unexpected end of file found
Error executing cl.exe.

temp.obj - 5 error(s), 0 warning(s)



他这个是 C语言写的,得用 C语言编译器。

把 .cpp 改成 .c 再试试。

还有 27 行 printf 里面加上你要输出的东西。

引用来自“水晶之夜”的答案

引用来自“中山野鬼”的答案

引用来自“NealFeng”的答案

定义个数组c=int[26][2],c[0][0]='a',c[0][1]=次数,然后排序,然后输出,如果次数为0,则不输出,选个排序算法就行了

哈,你这个貌似多做事情了。题目是针对字母,没针对其他分类方法。那么就可以直接

int alpha[26];

void init_alpha(void){
     int i; 
     for (i = 0 ; i < 26 ; i ++ ) alpha[i] = 0;
}
#define _CHK_SET(a,min,max) do {if((a >= (min))&&(a <= (max))){alpha[a-min] += 1;}while (0)
void set_alpha(char a){
     _CHK_SET(a ,'A','Z');
     _CHK_SET(a,'a','z');
}
int max_num(void){
    int re = alpha[0];
    int i;
    for (i = 1 ; i< 26 ; i++) {
         if (alpha[i] > re) re = alpha[i];
    }
    return re;
}
int print_max(void){
   int i;
   int flag = 0;
   i = max_num();
   if (alpha[i] == 0){
       return 0;
   }
   printf(....);
   alpha[i] = 0;
   return 1;
}



余下,就是初始化。然后读一个字符如果不是结束符,就掉用一次set_alpha,全部处理完就不停的调用print_max 直到返回为0.

哈, 原型设计不要考虑优化问题。逻辑清楚是关键。有什么好排序的。你排序的价值在于降低不必要的逻辑处理,但和目标逻辑没有关系。



我测试了你一下你这个代码,还有5个错误。不太理解。。

--------------------Configuration: temp - Win32 Debug--------------------
Compiling...
temp.cpp
d:\my files\c program\wow\temp\temp.cpp(25) : error C2062: type 'int' unexpected
d:\my files\c program\wow\temp\temp.cpp(26) : error C2143: syntax error : missing ';' before '{'
d:\my files\c program\wow\temp\temp.cpp(33) : error C2562: 'set_alpha' : 'void' function returning a value
        d:\my files\c program\wow\temp\temp.cpp(21) : see declaration of 'set_alpha'
d:\my files\c program\wow\temp\temp.cpp(35) : error C2601: 'print_max' : local function definitions are illegal
d:\my files\c program\wow\temp\temp.cpp(46) : fatal error C1004: unexpected end of file found
Error executing cl.exe.

temp.obj - 5 error(s), 0 warning(s)



这个也算代码?我的老天啊。。。无非是我想说明逻辑,用了语言来描述。。。。不能这么省事。又不是我的作业。哈。
顶部