C语言PAT刷题 - 1002 写出这个数

作者的话:若有朋友复制代码去PAT试着运行遇到问题的:
1.可能是格式问题,可以先把从本站复制的代码粘贴到记事本,再把记事本里的代码复制,然后粘贴到PAT的代码区,提交本题回答,应该就可以了;
2.可能是注释原因,PAT有时候检测到注释会编译错误,所以可以先把注释删了,再进行提交回答。
3.可能是作者当初根据题目写出来的代码仍存在一些疏漏,而恰好当时的测试机制没那么完善,没检测出问题。后面测试机制有所更新,故出现问题,若有相关需要的可以评论区留言或私信作者,我看到的话会去再查一下疏漏之处,然后更新文章。

一、题目描述

读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字。

输入格式:每个测试包含 1 个测试用例,即给出自然数 n 的值。这里保证 n 小于 10^100。

(样例:1234567890987654321123456789)

输出格式:在一行内输出 n 的各位数字之和的每一位,拼音数字间有 1 空格,但一行中最后一个拼音数字后没有空格。

(样例:yi san wu)

二、解题思路

读题:
接收不大于10^100的正整数,一般的整型无法存储这么大的数据,同时为了方便之后统计各位数字的和,我们可以采用字符数组来接收正整数n。之后用变量sum来统计n的各位之和,使用函数Spell实现数字转拼音的操作。

思路:

1.定义需要的变量(实际解题时是先定义认为需要用到的变量,后面遇到问题需要新定义变量时再回到上头来定义新的变量),从键盘接收一个正整数存入字符数组arr中;

2.设置一个循环以依次把字符数组中的各个元素(也就是正整数n的各位)累加在一起,并把结果存入sum;

3.设置判断,对<10的sum直接进行拼写,对>10的sum进行将其第一位、第二位依次转变为拼音,且每两位拼音数字之间添加空格的操作(仅仅留下写代码的位置,具体思路在下一步);

4.对>10的sum,可以设置循环,每一层循环便是sum当前最高位的打印(因为题目的要求是按从最高位到最低位的顺序打印拼音数字)。为了能得到sum的当前最高位,可以再设置一个循环,将sum不断作/10判断(为下一轮循环不丢失sum的后几位数字,可以先将sum赋值给i,然后对i进行操作,得到当前最高位的拼音数字后再对sum进行操作,去除最高位,开始下一轮循环),为0则表示当前位已经为最高位了,不为0则代表还不是最高位。直到得到最高位,对其进行数字转拼音操作;

5.设置count,在sum之前每次进行/10操作以让sum仅剩下最高位时,累计/10操作的次数,即得到sum当前最高位的位权(即它后面有几个数字,如23,2的位权是10^1),以便后面通过位权去除sum当前最高位;

6.设置判断,实现两个拼音数字之间留有空格,而最后一位拼音数字后面无空格的设想;

7.定义函数Spell,功能是将检测到的一位数以拼音形式打印;

8.对于一些特殊数字(如100),前面的程序仍存在缺陷,无法正确打印,所以在此设置新的循环以及判断语句,进行特殊数字的打印。

三、具体实现

0.标准C源程序框架

#include <stdio.h>
int main()
{
    return 0;
}

1.定义需要的变量(实际解题时是先定义认为需要用到的变量,后面遇到问题需要新定义变量时再回到上头来定义新的变量),从键盘接收一个正整数存入字符数组arr中;

	char arr[100] = { 0 };//用以接收正整数n
    int sum = 0;//用以存储正整数n各位之和
    int i = 0;//循环变量,用以将数组各位依次累加时作为循环条件
    int count = 0;//统计最高位位权,用以将最高位转化为拼音数字输出后,去除最高位
    scanf("%s", arr);//调用函数从键盘接收正整数n,存储在arr中

2.设置一个循环以依次把字符数组中的各个元素(也就是正整数n的各位)累加在一起,并把结果存入sum;

	i = strlen(arr) - 1;

	/*i作为循环变量用来把arr数组的每个元素存储到sum中,故要和数组元素个数相同(即等于strlen(arr)),又数组元素从0开始计数,所以i需要等于strlen(arr)-1*/
    for (i; i >= 0; i--)
    {
        sum += (arr[i] - '0');//arr中存储的是字符,在累加存储之前需要先减去字符'0',转化为数字
    }

3.设置判断,对<10的sum直接进行拼写,对>10的sum进行将其第一位、第二位依次转变为拼音,且每两位拼音数字之间添加空格的操作(仅仅留位置,具体思路在下一步);

	if (sum < 10)//如果sum<10,直接调用Spell函数,根据传过去的一位数,打印其拼音形式
        Spell(sum);
    else
    {
       //根据检测到的数字依次将其各个位上的数字以拼音形式进行输出
    }

4.对>10的sum,可以设置循环,每一层循环便是sum当前最高位的打印(因为题目的要求是按从最高位到最低位的顺序打印拼音数字)。为了能得到sum的当前最高位,可以再设置一个循环,将sum不断作/10判断(为下一轮循环不丢失sum的后几位数字,可以先将sum赋值给i,然后对i进行操作,得到当前最高位的拼音数字后再对sum进行操作,去除最高位,开始下一轮循环),为0则表示当前位已经为最高位了,不为0则代表还不是最高位。直到得到最高位,对其进行数字转拼音操作;

		while (sum != 0)//当sum不等于0的时候,说明还有别的位,继续循环输出拼音数字
        {                //这种方法的缺点是当遇到100的时候,打印完最高位1之后,难以继续打印
            i = sum;
            while (i / 10 != 0)//先判断i/10之后是否为0,若不为0,则表示现在的i还不是一位数
            {                         //故真正令其除以10,直到i/10为0,则其已经是一位数了
                i /= 10;           //不需要再对其进行除以10操作
            }                        //直接调用Spell函数打印i(也就是sum此时最高位)
            Spell(i);
        }

5.设置count,在sum之前每次进行/10操作以让sum仅剩下最高位时,累计/10操作的次数,即得到sum当前最高位的位权(即它后面有几个数字,如23,2的位权是10^1),以便后面通过位权去除sum当前最高位;

		while (sum != 0)
        {
            i = sum;
            count = 0;
            while (i / 10 != 0)
            {
                i /= 10;
                count++;//i除以10的操作进行几次,即代表i后面有几个数字,也就是i的位权
            }
            Spell(i);
            sum = sum - (int)(i * pow(10, count));//利用位权去除sum当前最高位
        }

6.设置判断,实现两个拼音数字之间留有空格,而最后一位拼音数字后面无空格的设想;

		while (sum != 0)
        {
            i = sum;
            count = 0;
            while (i / 10 != 0)
            {
                i /= 10;
                count++;
            }
            Spell(i);
            sum = sum - (int)(i * pow(10, count));
            if (count > 0)//当count大于0的时候,则证明i后面还有待打印的数字,需要输出空格
                printf(" ");//输出空格
        }
  1. 定义函数Spell,功能是将检测到的一位数以拼音形式打印;
void Spell(int p)//定义函数Spell,接收整型数P(本例中即sum的当前最高位)
{
    switch (p)//switch语句,根据p当前的值,选择不同的分支去执行相应的语句
    {
    case 0:    //当p为0的时候,就输出"ling",后面同理
    {
        printf("ling");
        break;
    }
    case 1:
    {
        printf("yi");
        break;
    }
    case 2:
    {
        printf("er");
        break;
    }
    case 3:
    {
        printf("san");
        break;
    }
    case 4:
    {
        printf("si");
        break;
    }
    case 5:
    {
        printf("wu");
        break;
    }
    case 6:
    {
        printf("liu");
        break;
    }
    case 7:
    {
        printf("qi");
        break;
    }
    case 8:
    {
        printf("ba");
        break;
    }
    case 9:
    {
        printf("jiu");
        break;
    }
    }
}

8.对于一些特殊数字(如100),前面的程序仍存在缺陷,无法正确打印,所以在此设置新的循环以及判断语句,进行特殊数字的打印。

			while (count && sum == 0)//当遇到个位为0的特殊数字,前面的代码会因sum为0不再继续打印

			/*故增加这个循环根据count(count就是上一个最高位后面数字的个数,此时去掉上一个最高位之后,sum为0,说明后面这几个数字都是0,0的个数就是count的值)对后面的0依次进行输出,并且只要当前位后面还有数字,就再输出一个空格,直到输出最后一位,不再输出空格。*/
            {                             
                printf("ling");
                count--;
                if (count > 0)
                    printf(" ");
            }

四、全部代码

#include <stdio.h>
#include <math.h>
#include <string.h>
void Spell(int p)
{
    switch (p)
    {
    case 0:
        {
            printf("ling");
            break;
        }
    case 1:
        {
            printf("yi");
            break;
        }
    case 2:
        {
            printf("er");
            break;
        }
    case 3:
        {
            printf("san");
            break;
        }
    case 4:
        {
            printf("si");
            break;
        }
    case 5:
        {
            printf("wu");
            break;
        }
    case 6:
        {
            printf("liu");
            break;
        }
    case 7:
        {
            printf("qi");
            break;
        }
    case 8:
        {
            printf("ba");
            break;
        }
    case 9:
        {
            printf("jiu");
            break;
        }
    }
}
int main()
{
    char arr[100] = { 0 };
    int sum = 0;
    int i = 0;
    int count = 0;
    scanf("%s", arr);
    i = strlen(arr) - 1;
    for (; i >= 0; i--)
    {
        sum += (arr[i] - '0');
    }
    if (sum < 10)
    {
        Spell(sum);
    }
    else
    {
        while (sum!=0)
        {
            i = sum;
            count = 0;
            while (i / 10 != 0)
            {
                i /= 10;
                count++;
            }
            Spell(i);
            sum = sum - (int)(i * pow(10, count));
            if (count > 0)
                printf(" ");
            while (count && sum == 0)
            {
                printf("ling");
                count--;
                if (count>0)
                {
                    printf(" ");
                }
            }
        }
    }
    return 0;
}
  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值