pat乙级 1002 题解

思维难度与编码难度均不大,当然对我现在的水平来说还是有一些挑战的,做出来也比较有成就感,可惜在一开始选择了错误的方向因而花费了许多时间

刚做过1001,受惯性思维影响,依然选择使用int变量去接受输入,但实际上1002中n的范围与1001(不超过 1000 的正整数)大相径庭,不能作相同处理。本题中n的范围是小于10^100,直观感觉是1后面跟100个0,这个数字已经远远超过了long long类型所能表示的最大数值,所以需要用字符串数组去接受输入

正确的解法放在后面再谈,先说最初的错误的解法

代码如下:

#include <stdio.h>

#include <stdlib.h>

int sum(int n);

void printsum(int sum);

int main()

{

    int n;

    scanf("%d",&n);

    printsum(sum(n));

    return 0;

}

int sum(int n)

{

    int shang;

    int yushu=0;

    int sum=0;

    for(shang=n;shang>=10;)

    {

        shang=n/10;

        yushu=n%10;

        n=shang;

        sum=sum+yushu;

    }

    sum=sum+shang;

    return sum;

}

void printsum(int sum)

{

    char string[1024];

    sprintf(string,"%d",sum);

    int i;

    for(i=0;string[i];i++)

    {

        switch(string[i])

        {

            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;

        }

        if(string[i+1]) printf(" ");

    }

}

零、错误原因:

接受输入的n值时选择数据类型出错,错在未认真考虑n的范围,选择以int变量而非字符串数组存储n值

一、整体思路:

1.通过int变量读入n值后,依次取出n的每一位进行求和,得到存有各位数字之和的int变量sum

2.从高到低依次取出sum的每一位,输出对应值

二、关键问题:

1.如何依次取出一个数的每一位

2.如何从高到低依次取出一个数的每一位

最初没有认真思考应该如何解决2,习惯性地去解决1,于是整体的解题思路近似于先走1再走2。现在回顾起来,其实可以走两步2,即先从高到低取出n的每一位并进行求和得到sum,再从高到低取出sum的每一位并进行输出,这样从高到低的实现代码部分就实现了复用

三、关键问题对应的解决方法:

1.循环进行除与取余操作,每次令被除数为之前运算得到的商,通过余数得到数n从低到高取出的下一位

例如:1234/10=123,1234%10=4,4是1234的最后一位

           123/10=12,123%10=3,3是1234的倒数第二位

2.将int型变量存储的数值转换为对应的字符串(sprintf),通过对字符串的相应操作实现从高到低取出每一位

四、一些小细节:

1.记得进行函数声明,需要加分号

2.想要将整形变量转换为字符串时,记得选择sprintf而非itoa,因为后者是Windows上所特有的非标准C函数

3.声明字符串变量不能仅仅只是char * string,这样只是声明了一个指针却没有将其指向内存中的具体位置,之后若不作处理就跟sprintf,程序运行会出错 

现在再说正确的,用字符串存储n值的解法

分析:

在选择(被迫)用字符串存储n值后,依次取出n的每一位(无论是从高到低还是从低到高)这一想法通过对字符串的相应操作就变得十分简单了,在此基础上进行求和得到sum,之后的过程同错解是一致的

代码如下:

#include <stdio.h>

#include <stdlib.h>

int sum(char * n);

void printsum(int sum);

int main()

{

    char n[101];

    scanf("%s",n);

    printsum(sum(n));

    return 0;

}

int sum(char * n)

{

    int i;

    int sum=0;

    

    for(i=0;n[i];i++)

    {

        switch(n[i])

        {

            case '0':break;

            case '1':sum+=1;break;

            case '2':sum+=2;break;

            case '3':sum+=3;break;

            case '4':sum+=4;break;

            case '5':sum+=5;break;

            case '6':sum+=6;break;

            case '7':sum+=7;break;

            case '8':sum+=8;break;

            case '9':sum+=9;break;

        }

    }

    return sum;

}

void printsum(int sum)

{

    char string[1024];

    sprintf(string,"%d",sum);

    int i;

    for(i=0;string[i];i++)

    {

        switch(string[i])

        {

            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;

        }

        if(string[i+1]) printf(" ");

    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值