STD高级语言程序设计第九天(满分答案,附赠本人程序的解析及坑点标识)

7-1 纸牌排序 (10 分)

小诺诺喜欢玩纸牌比大小的游戏。现在有一副牌中的若干张纸牌,需要按牌面的数字从大到小的顺序排列,若数字大小相同则按花色从大到小(黑桃>红桃>梅花>方块)排列。牌面为A、J、Q、K分别用1、11、12、13表示;花色中的黑桃、红桃、梅花、方块分别用英文单词"spade"、"heart"、"club"、"diamond"表示。

输入格式:

测试数据有多组,首先输入测试的组数T (0<T<10),然后是T组测试数据;每组测试输入一行,按“花色 数字”的格式输入若干张牌,花色可能为"spade"、"heart"、"club"、"diamond"之一,数字为1~13。输入的数据之间可能有若干(至少1个)空格,在行的首尾也可能有若干空格,但每组输入数据的总长度不会超过1000个字符。

输出格式:

每组测试输出一行,按描述中的排序规则从大到小输出牌的信息,数据之间都以一个空格分隔。

输入样例:

2
 diamond 1 club 1  heart 1  spade 3 diamond 2 club 3 heart 2  
diamond 13 club 13 heart 13    spade 12

输出样例:

spade 3 club 3 heart 2 diamond 2 heart 1 club 1 diamond 1
heart 13 club 13 diamond 13 spade 12
#include<stdio.h>
#include<string.h>
int main()
{
    //存储并接收组数
    int a;
    scanf("%d",&a);
    
    //吃数字后面的回车
    //但凡以后遇见数字回车,字符,一定要加上getchar,否则计算机会把数字后面的回车当做字符处理
    getchar();
    
    //循环输入每组牌
    for(int i=0;i<a;i++)
    {
        //存储每组牌
        //小编觉得要将每组牌存储在一个大数组中
        //因为题干有提示首尾有若干空格
        //所以我觉得scanf("%s %d",char*_,int_)这种格式可能接收不到末尾的空格
        //哪怕后面加上getchar也只能接受一个空格,而空格的数量是不确定的
        //导致空格或者回车可能会存储到下一组的字符数组里面,这样的程序肯定错误
        char b[1001];
        
        //接收牌
        gets(b);
        
        //存储牌的数量
        int c=0;
        
        //存储牌的花色
        char d[500][20];
        
        //存储牌的大小
        int e[500]={0};
        
        //控制d数组每个花色字符串的结束
        int k=0;
        
        //将大数组牌的花色和大小分别存储到两个数组中
        for(int j=0;j<strlen(b);j++)
        {
            //判断是否是字母,如果是,存储到d数组中,以空格为标志结束
            if(b[j]>='a'&&b[j]<='z')
            {
                //第一维控制每个花色
                //第二位控制每个花色的字母
                d[c][k++]=b[j];
                
                //如果该字母后面是空格,证明本花色字符串结束
                if(b[j+1]==' ')
                {
                    //结束每个花色,字符串以'\0'作为结束标志
                    d[c][k]='\0';
                    
                    //将k赋值0,准备接收下一个花色
                    k=0;
                    
                    //小编这种字符串也有些不确定,打印出来看一下前面程序的正确性
                    //printf("%s ",d[c]);
                }
            }
            
            //判断是否是数字
            else if(b[j]>='0'&&b[j]<='9')
            {
                e[c]=e[c]*10+b[j]-'0';
                
                //如果改数字后面是'\0'或者' '说明数字结束
                //将控制第一维的变量c加一
                //准备接收下一个牌的花色和大小
                //d数组和e数组的角标相互对应
                if(b[j+1]=='\0'||b[j+1]==' ')
                {
                    //同样,打印一下,看一下效果,校验前面代码是否符合要求
                    //printf("%d\n",e[c]);
                    c++;
                }
            }
        }
        
        //上面代码执行完毕,说明花色和大小已经分别存储在两个数组中
        //进行下一步,排序
        for(int j=0;j<c;j++)
        {
            for(int k=j+1;k<c;k++)
            {
                //作为交换时的中间变量
                char tp[20];
                
                //先比较大小,如果前面的牌比后面的小,调换一下位置
                if(e[j]<e[k])
                {
                    //先交换大小
                    int temp=e[j];
                    e[j]=e[k];
                    e[k]=temp;
                    
                    //因为d数组存储的花色和e数组存储的大小的角标是相互对应的
                    //d数组也要进行交换
                    //因为d数组里面是字符串
                    //所以要用字符串复制的函数strcpy
                    //如果用赋值即“=”程序报错
                    strcpy(tp,d[j]);
                    strcpy(d[j],d[k]);
                    strcpy(d[k],tp);
                }
                
                //大小相同,比较花色
                else if(e[j]==e[k])
                    
                    //因为每个花色的首字母不同,所以我们可以根据首字母判断花色
                    //如果前一张牌的花色是‘d’,则一定小于后一张牌的花色,交换花色
                    //如果后一张牌的花色是‘s’,则一定大于前一张牌的花色,交换花色
                    //如果前一张牌的花色是‘c’,后一张牌的花色是‘h’
                    //前一张牌的花色小于后一张牌的花色,交换花色
                    //就这三种情况,如果花色不是‘d’和‘s’,那就只能是‘c’和‘h’
                    //同理,如果有一个是‘c’,另一个不是‘h’,则一定是‘d’或‘s’
                    //其他情况则无需交换花色
                    if(d[j][0]=='d'||d[k][0]=='s'||(d[j][0]=='c'&&d[k][0]=='h'))
                    {
                        //同理,利用函数交换字符串
                        strcpy(tp,d[j]);
                        strcpy(d[j],d[k]);
                        strcpy(d[k],tp);
                    }
            }
        }
        
        //打印,因为结尾没有空格,所以只打印到倒数第二个
        for(int j=0;j<c-1;j++)
            printf("%s %d ",d[j],e[j]);
        
        //打印最后一个,并换行
        printf("%s %d\n",d[c-1],e[c-1]);
    }
    
    return 0;
}

虽然第一题只有十分,但是小编觉得这道题比二十分的题还要恶心人,最直观的体验就是卡了很多人,而且是一份都没有,最简单的就是输入不规则, 一半的代码都是在切割空格,将花色和大小存储到数组中,另外就是花色比大小,如果不像小编这么聪明,就一个一个的比较,小编算了一下,六种情况,对C语言没那么熟悉的人可能还会用“==”去比较,程序代码肯定很长,而且健壮性弱,字符串也不能简单的去赋值,这道题小编觉得主要就是字符串的函数的考察,用好了,事半功倍,用不好,懂得都懂!!!小编在没有写注释的时候,代码就写了70行,所以这道题还是不太符合他的分数,如果小编存在不足,还望大神赐教!!!

 7-2 找最大字符 (10 分)

从键盘上输入一个字符串(最多80个字符),找出其中最大的字符并输出,最后换行。

输入格式:

从键盘上输入一个字符串(最多80个字符)。

输出格式:

找出其中最大的字符并输出,最后换行。

输入样例1:

987654321

输出样例1:

9

输入样例2:

abczdefg

输出样例2:

z

输入样例3:

123456789

输出样例3:

9

 

#include<stdio.h>
#include<string.h>
int main()
{
    //接收并存储字符串
    char a[81];
    gets(a);
    
    //存储第一个字符的ASCII码
    int b;
    
    //强制类型转换,变成字符的ASCII码值
    b=(int)a[0];
    
    //循环转换
    for(int i=1;i<strlen(a);i++)
    {
        //存储第二个开始的ASCII
        int c;
        c=(int)a[i];
        
        //比较,将最大的ASCII存储在b中
        if(c>b)
            b=c;
    }
    
    //存储最大的字符
    char d;
    
    //将ASCII码强制转换为字符
    d=(char)b;
    
    //打印
    printf("%c\n",d);
    
    return 0;
}

第二题小编直接就比较的ASCII,小编认为测试点可能是数字和字母或者符号混合,如果单纯的认为输入的都是同一种类型,可能会出错,小编也没有试,另外小编也觉得比较ASCII代码更加简洁一些。健壮性也很高!!! 

 7-3 统计一行文本的单词个数 (15 分)

本题目要求编写程序统计一行字符中单词的个数。所谓“单词”是指连续不含空格的字符串,各单词之间用空格分隔,空格数可以是多个。

输入格式:

输入给出一行字符。

输出格式:

在一行中输出单词个数。

输入样例:

Let's go to room 209.

输出样例:

5

鸣谢用户 张麦麦 补充数据!

#include<stdio.h>
int main()
{
    //存储文本
    char str[1000];
    
    //不能用scanf,文本前面存在空格,会将空格存储到str中
    //后面的文本会继续存在缓冲区,等待下一个scanf的接收
    //而gets则会遇见回车停止接收字符
    //所以本题一定要用gets
    gets(str);
    
    //count存储单词的个数
    //i计算字符串的每个字母位置
    int count=0,i=0;
    
    //循环判断
    while(str[i]!='\0')
    {
        //如果本个字符不是空格且下一个字符是空格,或者下一个字符是'\0'
        //证明一个单词的结束
        //count加一
        if((str[i+1]=='\0'||str[i+1]==' ')&&(str[i]!=' '))
            count++;
        i++;
    }
    
    //打印
    printf("%d\n",count);
    
    return 0;
}

第三题主要就是注意开头的空格,字符串必须用gets接收,还有判断一个单词的结束,挺简单的!!! 

 7-4 将整数转换为汉字大写数字 (15 分)

从键盘输入一个3位的正整数,将其中的每一位数字转换为相应的汉字大 写数字输出。

输入格式:

一个3位的正整数。

输出格式:

汉字大写数字字符串,最后换行。

输入样例:

139

输出样例:

壹叁玖

 

#include<stdio.h>
int main()
{
    //接收,存储三位数字为字符串
    char a[4];
    gets(a);
    
    //存储大写数字,一个英文符号占据一个字节
    //一个汉字在不同的编译环境占据不同的字节
    //所以数组的第二维一定要存在且不能小,否则程序报错
    char b[10][10]={"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};
    
    //循环打印三位数字的大写
    for(int i=0;i<3;i++)
        
        //a[i]是字符串的第一个数,但他是char类型,减'0'间接转化为int型
        //b数组的角标与数字相互对应
        printf("%s",b[a[i]-'0']);
    
    //打印换行
    printf("\n");
    
    return 0;
}

 最后一题就是存储大写汉字的数组那里,第二维一定要存在,不然程序肯定会报错,汉字和英文字母不一样!!!

看在小编这么努力的份上,给小编点个赞呗!!!

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力敲代码啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值