思维难度与编码难度均不大,当然对我现在的水平来说还是有一些挑战的,做出来也比较有成就感,可惜在一开始选择了错误的方向因而花费了许多时间
刚做过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(” “);
}
}