黑马程序员技术交流社区

标题: 基础测试遇到问题,求大神来指教吧 [打印本页]

作者: caopengxu    时间: 2014-7-16 22:29
标题: 基础测试遇到问题,求大神来指教吧
/*
7、 从键盘输入一大堆字符串,统计A、B、C、D的出现次数,
最后出现次数由高到低输出字母和出现次数。(C语言)

解题思路:
*/
#include<stdio.h>

void PaiXu(int,int,int,int);

int main()
{
    int i,a = 0,b = 0,c = 0,d = 0;
    char f[100];
    printf("请输入字符串(以空格隔开):\n");
    scanf("%s",f);
   
    for(i = 0;f[i] != '\0';i++)
    {
        if(f[i] == 'A')
            a++;
        else if(f[i] == 'B')
            b++;
        else if(f[i] == 'C')
            c++;
        else if(f[i] == 'D')
            d++;
    }
   
    printf("%d%d%d%d\n",a,b,c,d);
    PaiXu(a,b,c,d);
    return 0;
}

void PaiXu(int a,int b,int c,int d)
{
    int i,j,max,x[4] = {a,b,c,d};
   
    for(i = 0;i < 3;i++)
    {
        for(j = i + 1;j < 4;j++)
        {
            if(x[i] < x[j])
            {
                max = x[i];
                x[i] = x[j];
                x[j] = max;
            }
        }
    }
   
    for(i = 0;i < 4;i++)
    {
        if(x[i] == a)
            printf("%c",'A');
        else if(x[i] == b)
            printf("%c",'B');
        else if(x[i] == c)
            printf("%c",'C');
        else
            printf("%c",'D');
        
        printf(":%d次\n",x[i]);
    }
}
问题:如果输入的ABCD的个数有相同的,会出现打印错误。
作者: yingzhuo1314    时间: 2014-7-16 22:54
本帖最后由 yingzhuo1314 于 2014-7-16 23:01 编辑


  1. struct test        //定义一个结构体数组
  2.         {
  3.                 int b;   //存储字符出现的次数
  4.                 char c;  //存储字符A、B、C、D
  5.         } t[4];
  6. void selectsort(struct test *b,int n)    //选择排序
  7. {
  8.         int i,j,k,temp; //定义int类型变量
  9.         char tem;     //定义char类型变量
  10.         for(i=0;i<n;i++)   //使用for循环遍历字符串
  11.         {
  12.                 k=i;  //将i赋值给变量k
  13.                 for(j=i+1;j<n;j++)  //使用for循环遍历i之后的字符串
  14.                         if(b[k].b<b[j].b)   //判断第j个字符出现的次数和第i个字符出现的次数的大小
  15.                                 k=j;  //将j赋值给变量k
  16.                         //以下数据交换变量i和变量k中的数据
  17.                         temp=b[i].b;     
  18.                         b[i].b=b[k].b;
  19.                         b[k].b=temp;
  20.                         tem=b[i].c;
  21.                         b[i].c=b[k].c;
  22.                         b[k].c=tem;
  23.         }
  24.         
  25. }
  26. #include<string.h>
  27. #include <stdio.h>
  28. void main()
  29. {
  30.         //int b[4];
  31.         int i,sumA,sumB,sumC,sumD;  //定义int型变量
  32.         sumA=sumB=sumC=sumD=0; //对sumA,sumB,sumC,sumD赋初值0
  33.    char a[100];  //定义一个字符数组
  34.    printf("请输入字符串:");
  35.    gets(a);   //从键盘端输入字符串
  36.    printf("%s\n",a);  //输出刚输入的字符串
  37.    for(i=0;i<100;i++)    //统计A、B、C、D出现的次数
  38.    {
  39.            if(a[i]=='A')  //统计A的个数
  40.                    sumA++;
  41.            else if(a[i]=='B')  //统计B的个数
  42.                    sumB++;
  43.            else if(a[i]=='C')   //统计C 的个数
  44.                    sumC++;
  45.            else if(a[i]=='D')   //统计D的个数
  46.                    sumD++;
  47.                   
  48.    }
  49.    printf("A出现的次数为:%d\nB出现的次数为:%d\nC出现的次数为:%d\nD出现的次数为:%d\n",sumA,sumB,sumC,sumD); //输出A、B、C、D的个数
  50.    t[0].b=sumA;t[1].b=sumB;t[2].b=sumC;t[3].b=sumD;  //对结构体中的变量b赋值
  51.    t[0].c='A';t[1].c='B';t[2].c='C';t[3].c='D';     //对结构体中的变量c赋值
  52.    selectsort(t,4);   //调用排序函数
  53.    printf("出现次数由高到低的字母和出现次数为:\n"); //输出
  54.    printf("字母        出现次数\n");   //输出
  55.    for(i=0;i<4;i++)     //以下语句输出最终结果
  56.    printf("%c\t        %d\n",t[i].c,t[i].b);
  57. }
复制代码

作者: yingzhuo1314    时间: 2014-7-16 23:12
你代码的最后一个for循环中,x[i]=a中的a是一个具体的整数,当你输入的A和B的个数相同时,都是会执行第一个if语句 的,所以输出的字母都会是A ,比如你输入的字符串是AAABBBCCD,此时a的值为3,当i=0时x[0]=3,执行第一个if语句,输出字母A,i=1时x[1]也等于3,执行的还是第一个if语句,输出的也是A,故会出现输出错误
作者: caopengxu    时间: 2014-7-16 23:15
yingzhuo1314 发表于 2014-7-16 22:54

恩,启发挺大的,感谢。
作者: caopengxu    时间: 2014-7-16 23:21
yingzhuo1314 发表于 2014-7-16 23:12
你代码的最后一个for循环中,x=a中的a是一个具体的整数,当你输入的A和B的个数相同时,都是会执行第一个if ...

解决方案有木有。
作者: yingzhuo1314    时间: 2014-7-16 23:34
caopengxu 发表于 2014-7-16 23:21
解决方案有木有。

我发给你的那个代码可以实现这个题目的功能
作者: 温天恩    时间: 2014-7-16 23:51
  1. #import <stdio.h>

  2. // 定义一个主函数,作为程序的入口
  3. int main()
  4. {
  5.     // 定义一个数组array用来存放输入的字符串
  6.     char array[100];
  7.    
  8.     // 提示输入一个字符串
  9.     printf("请输入一串字符串:\n");
  10.    
  11.     // 接收输入的字符串,并赋值给数组array
  12.     scanf("%s",array);
  13.    
  14.     // 定义两个变量用于for循环条件变量
  15.     int i,j;
  16.    
  17.     // 定义四个变量用来存放ABCD出现的次数
  18.     int a = 0;
  19.     int b = 0;
  20.     int c = 0;
  21.     int d = 0;
  22.    
  23.     // 定义变量length用来存放输入字符串的长度
  24.     unsigned long length = strlen(array);
  25.    
  26.     // 定义for循环,当i小于字符串长度时,执行循环体,i加1
  27.     for (i = 0; i<length; i++) {
  28.         
  29.         // 统计A出现的次数
  30.         if (array[i] == 'A') {
  31.             a++;
  32.         }
  33.         
  34.         // 统计B出现的次数
  35.         else if (array[i] == 'B'){
  36.             b++;
  37.         }
  38.         
  39.         // 统计C出现的次数
  40.         else if (array[i] == 'C'){
  41.             c++;
  42.         }
  43.         
  44.         // 统计D出现的次数
  45.         else if (array[i] == 'D'){
  46.             d++;
  47.         }
  48.     }
  49.    
  50.     // 定义一个数组x用来存放ABCD出现的次数
  51.     int x[4] = {a,b,c,d};
  52.    
  53.     // 定义temp用于冒泡排序标记排序趟数
  54.     int temp;
  55.    
  56.     // 冒泡排序  将a,b,c,d降序排序,i表示排序的趟数,j表示每趟排序的比较次数
  57.     for (i = 0; i<3; i++)
  58.     {
  59.         for(j = 0;j<3-i;j++)
  60.         {
  61.             if (x[j] < x[j+1])
  62.             {
  63.                 // 当前一个元素小于后一个元素时,交换它们的位置
  64.                 temp = x[j];
  65.                 x[j] = x[j+1];
  66.                 x[j+1] = temp;
  67.             }

  68.         }
  69.     }
  70.    
  71.     // 定义一个数组y用来存放ABCD标志
  72.     char y[4];
  73.    
  74.     // 将数组x与数组y的出现次数和标志一一对应
  75.     for (i = 0; i<4; i++)
  76.     {
  77.         // 如果出现a次,则y[i]='A'
  78.         if(x[i] == a && y[0] != 'A' && y[1] != 'A' && y[2] != 'A' && y[3] != 'A')
  79.         {
  80.             y[i] = 'A';
  81.         }
  82.         // 如果出现b次,则y[i]='B'
  83.         else if(x[i] == b && y[0] != 'B' && y[1] != 'B' && y[2] != 'B' && y[3] != 'B')
  84.         {
  85.             y[i] = 'B';
  86.         }
  87.         // 如果出现c次,则y[i]='C'
  88.         else if(x[i] == c && y[0] != 'C' && y[1] != 'C' && y[2] != 'C' && y[3] != 'C')
  89.         {
  90.             y[i] = 'C';
  91.         }
  92.         // 如果出现d次,则y[i]='D'
  93.         else
  94.         {
  95.             y[i] = 'D';
  96.         }
  97.     }
  98.    
  99.     // 降序打印输出每个字母出现的次数
  100.     for (i = 0; i<4; i++)
  101.     printf("%c出现%d次\n",y[i],x[i]);
  102.    
  103.     return 0;
  104. }
复制代码

楼主可以试试看!我的代码是没问题的,你可以优化一下。
作者: caopengxu    时间: 2014-7-17 00:07
温天恩 发表于 2014-7-16 23:51
楼主可以试试看!我的代码是没问题的,你可以优化一下。

给力,有过这个思路,但没想到具体的方法,感谢。
作者: 可心来了    时间: 2014-7-17 00:08
大家都这么给力的啊
作者: 443201683@qq.co    时间: 2014-7-17 00:49
按照楼主的思路修改,修改处已经注释了。用二维数组代替原来的一维数组就好了。

  1. #include"stdlib.h"
  2. #include<stdio.h>
  3. #include <ctype.h>
  4. void PaiXu(int,int,int,int);

  5. int main()
  6. {
  7.      int i,a = 0,b = 0,c = 0,d = 0;
  8.      char f[100];
  9.      printf("请输入字符串(以空格隔开):\n");
  10.      gets_s(f);
  11.          printf("%s",f);
  12.      for(i = 0;f[i] != '\0';i++)
  13.      {
  14.          if(f[i] == 'A')
  15.              a++;
  16.          else if(f[i] == 'B')
  17.              b++;
  18.          else if(f[i] == 'C')
  19.              c++;
  20.          else if(f[i] == 'D')
  21.              d++;
  22.      }
  23.      
  24.      printf("%d%d%d%d\n",a,b,c,d);
  25.      PaiXu(a,b,c,d);
  26.      return 0;
  27. }

  28. void PaiXu(int a,int b,int c,int d)
  29. {
  30.          int i,j,max,x[4][4] = {{a,1},{b,2},{c,3},{d,4}}; //此处用二维数组代替,第二列用来表示ABCD字符。
  31.      
  32.      for(i = 0;i < 3;i++)
  33.      {
  34.          for(j = i + 1;j < 4;j++)
  35.          {
  36.              if(x[i][0] < x[j][0])
  37.              {
  38.                  max = x[i][0];
  39.                  x[i][0] = x[j][0];
  40.                  x[j][0] = max;
  41.                                  max = x[i][1];
  42.                  x[i][1] = x[j][1];
  43.                  x[j][1] = max;
  44.              }
  45.          }
  46.      }
  47.      
  48.      for(i = 0;i < 4;i++)
  49.      {
  50.         if(x[i][1] == 1)
  51.              printf("A");
  52.          else if(x[i][1] == 2)
  53.              printf("B");
  54.          else if(x[i][1] == 3)
  55.              printf("C");
  56.          else
  57.              printf("D");
  58.          
  59.          printf(":%d次\n",x[i][0]);
  60.      }
  61.          system("pause");
  62. }
复制代码

作者: caopengxu    时间: 2014-7-17 09:25
443201683@qq.co 发表于 2014-7-17 00:49
按照楼主的思路修改,修改处已经注释了。用二维数组代替原来的一维数组就好了。

...

是诶,又一种思路,感谢。
作者: caopengxu    时间: 2014-7-17 09:53
yingzhuo1314 发表于 2014-7-16 22:54

你这应该会有警告吧,提示gets( )不安全。
作者: yingzhuo1314    时间: 2014-7-17 17:10
caopengxu 发表于 2014-7-17 09:53
你这应该会有警告吧,提示gets( )不安全。

已经编译过,木有警告~~
作者: caopengxu    时间: 2014-7-17 17:13
yingzhuo1314 发表于 2014-7-17 17:10
已经编译过,木有警告~~

啊,我回头再研究研究。
作者: 小海    时间: 2014-7-17 22:06
我有一点修改在for循环里打印语名后加上x[i] -= 1000;这样再怎么循环也不会重复了,自加还是有可能重复的
作者: 这个夏天的芬芳    时间: 2014-7-17 23:07
{:2_31:}{:2_31:}{:2_31:}{:2_31:}{:2_31:}{:2_31:}
作者: rocki    时间: 2014-7-18 08:25
yingzhuo1314 发表于 2014-7-17 17:10
已经编译过,木有警告~~

不是X-code编译的把。。X-code用gets函数给警告的。
作者: 冷水泡脚    时间: 2014-9-25 02:06
温天恩 发表于 2014-7-16 23:51
楼主可以试试看!我的代码是没问题的,你可以优化一下。

没能理解到如何将排序和字母对应起来,能简单描述一下思路吗?
作者: longshaocn    时间: 2014-9-25 09:47
之前基础测试的时候也有这道题,纠结了好几天。。
作者: 枫叶路过123    时间: 2014-11-3 12:51
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<time.h>
#pragma warning(disable:4996)

void swap(int *a, int *b)//交换位置
{
        int tmp = *b;
        *b = *a;
        *a = tmp;
}
void getsort(int *a, int *b, int *c, int *d)//冒泡排序
{
        int data[4] = { a, b, c, d };
        for (int i = 0; i < 3; i++)
        {
                for (int j = 1; j < 3 - i; j++)
                {
                        if (data[j - 1] < data[j])
                                swap(&data[j - 1], &data[j]);
                }
        }
        int add[4];
        for (int i = 0; i < 4; i++)
        {
                if (data[i] == a)
                        add[i] = 'A';
                else if (data[i] == b)
                        add[i] = 'B';
                else if (data[i] == c)
                        add[i] = 'C';
                else
                        add[i] = 'D';
        }
        for (int i = 0; i < 4; i++)
        {
                printf("%c %d\n", add[i], data[i]);
        }
}
int main()
{
        int a = 0;
        int b = 0;
        int c = 0;
        int d = 0;
        char buf[100];
        scanf_s("%s\n", buf);
        int len = strlen(buf);
        for (int i = 0; i<len; i++)
        {
                if (buf[i] == 'A')
                a++;
                else if (buf[i] == 'B')
                b++;
                else if (buf[i] == 'C')
                c++;
                else if(buf[i] == 'D')
                d++;
        }
        //printf("%d%d%d%d\n", a, b, c, d);//输出ABCD出现的次数
        getsort(&a,&b,&c,&d);//排序打印
        return 0;
}

作者: Zeus-S    时间: 2015-2-10 22:18
温天恩 发表于 2014-7-16 23:51
楼主可以试试看!我的代码是没问题的,你可以优化一下。

看到57行之后脑子就转不动打结了,
作者: yuang4074    时间: 2015-2-28 18:40
yingzhuo1314 发表于 2014-7-16 22:54

for(i=0;i<n;i++)   //使用for循环遍历字符串
        {
              //  k=i;  //将i赋值给变量k
                for(j=i+1;j<n;j++)  //使用for循环遍历i之后的字符串
                        if(b.b<b[j].b) {  //判断第j个字符出现的次数和第i个字符出现的次数的大小
                            //    k=j;  //将j赋值给变量k
                        //以下数据交换变量i和变量k中的数据
                        temp=b.b;     
                        b.b=b[j].b;
                        b[j].b=temp;
                        tem=b.c;
                        b.c=b[j].c;
}//这样也行。你为什么把//将i赋值给变量k //将j赋值给变量k

作者: chaoren    时间: 2015-3-4 15:45
我们可以标记三个变量用来标记打印或者未打印。
// 从键盘输入一大堆字符串,统计A、B、C、D的出现次数,最后出现次数由高到低输出字母和出现次数。
#include <stdio.h>
#include <string.h>
int main()
{   
//定义一个字符串
    char array[100];
//提示输入字符串
    printf("请输入一串字符串:\n");
    scanf("%s",array);
//printf("刚刚输入的字符串是:%s\n",array);
    //申明要调用的函数
void count(char [100]);
//将输入的字符串作为形参,调用count函数进行运算。
    count(array);
return 0;
}
void count(char array[100])  
{
    int a = 0;//用a来记录A出现的次数
    int b = 0;//用b来记录B出现的次数
    int c = 0;//用c来记录C出现的次数
    int d = 0;//用d来记录D出现的次数
    unsigned long length = strlen(array);
int i,j,temp;
for (i = 0; i<length; i++)
{
        if (array[i] == 'A') {//统计A出现的次数
            a++;
        }
        else if (array[i] == 'B'){//统计B出现的次数
            b++;
        }
        else if (array[i] == 'C'){//统计C出现的次数
            c++;
        }
        else if (array[i] == 'D'){//统计D出现的次数
            d++;
        }
    }
    //printf("A出现了%d次\tB出现了%d次\tC出现了%d次\tD出现了%d次\n",a,b,c,d);
int x[4] = {a,b,c,d};//定义一个数组存放次数
//用冒泡法给这个数组里面的次数按照从大到小的顺序排序
    for (i = 0; i<3; i++)//排序的趟数
    {
        for(j = 0;j<3-i;j++)//每趟比较次数
        {
            if (x[j] < x[j+1])//如果前一个数比后一个数要小,则借助第三方变量temp交换位置
            {
                temp = x[j];
                x[j] = x[j+1];
                x[j+1] = temp;
            }
        }
}


//为了防止出现次数相同重复打印的情况给打印的语句做一个标记0代表未打印,1代表已打印
int a1=0;
int b1=0;
int c1=0;
for(i=0;i<4;i++){
  if(x[i]==a && a1==0){//当a=b=c=d,如果没有打印标记,那么将重复打印第一条语句
      a1++;//打印标记
   printf("A出现了%d次\n",x[i]);
  }
  else if(x[i]==b && b1==0){
   b1++;//打印标记
   printf("B出现了%d次\n",x[i]);
  }
  else if(x[i]==c && c1==0){
   c1++;//打印标记
   printf("C出现了%d次\n",x[i]);
  }else printf("D出现了%d次\n",x[i]);//在if最后一个判断条件,所以不需标记。
}
}


作者: 陈明辉    时间: 2015-3-20 09:53
这个题困扰了我一天,来看看思路,我写的代码运行后出问题:Q
作者: Never_Yg    时间: 2015-6-2 13:11
感觉关键点就是对应字母的次数排序后,原来字母的关系没办法对应!好苦恼
作者: springD    时间: 2015-12-5 02:22
443201683@qq.co 发表于 2014-7-17 00:49
按照楼主的思路修改,修改处已经注释了。用二维数组代替原来的一维数组就好了。

...

给力,按照你的思路想通了。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2