开发者社区> 问答> 正文

C语言:输入一串字符,以‘?’结束,统计各字母出现的次数,并按字母出现的多少输出? 400 报错

C语言:输入一串字符,以‘?’结束,统计各字母出现的次数,并按字母出现的多少输出? 400 报错

有一个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);
	}
}




展开
收起
爱吃鱼的程序员 2020-06-03 16:15:57 1192 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB

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

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

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

    链表啊,结构体里放一个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.

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



    ######有一点挺有意思的,确实,要求是打印出来,干嘛排序呢?######

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

    引用来自“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)



    这个也算代码?我的老天啊。。。无非是我想说明逻辑,用了语言来描述。。。。不能这么省事。又不是我的作业。哈。
    2020-06-03 17:27:31
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载