全国大学生C语言程序设计大赛
第一套卷复现
程序改错1--回文数
本题目bug:未声明0是回文数。根据数学定义和权威解析,0满足正反读相同的条件,且被明确归类为回文数的特殊情形,正确答案里面是把0当做回文数的,但题目里面却只声明了回文数是正整数
题目:
1、程序改错1--回文数
- 允许编程的语言
C
- 题目描述
任务描述
“回文”是指具有“左右对称,正读反读都一样”特点的句子,它是古今中外都有的一种修辞方式和文字游戏。 例如:“雾锁山头山锁雾”、“天连水尾水连天”、“客上天然居,居然天上客”、“人过大佛寺,寺佛大过人”等等,这些句子都是“回文”。
一个正整数,如果正反顺序都表示一个数,这个整数也可以称为“回文数”。 例如:5、121、123454321、8899988 等都是回文数,而 123、456456、10086 等都不是回文数。
本题程序的功能是读入一个整数,输出这个整数是否为回文数。 提示:代码中/FOUND/的下一行是有问题的代码,请在这一行中修改,不要修改其它代码,不要增加和删除代码行。 初始代码:
#include<stdio.h>
/***********found***************/
long int fun(double m){
int m=0;
/***********found***************/
while(n>10){
m=m*10+n%10;
n=n/10;
}
return m;
}
int main(){
long int n;
scanf("%ld",&n);
/***********found***************/
if(fun(n))
printf("%ld是回文数",n);
else
printf("%ld不是回文数",n);
return 0;
}
- 输入格式
一个正整数,该整数的正序、反序都不超过long int类型。
- 输出格式
按输出样例形式,输出这个数是或不是回文数。
输入样例1: 1 输出样例1: 1是回文数
输入样例2: 121 输出样例2: 121是回文数
输入样例3: 1234 输出样例3: 1234不是回文数
输入样例4: 99899 输出样例4: 99899是回文数
解题:
原程序
#include<stdio.h>
/***********found***************/
long int fun(double m){
int m=0;
/***********found***************/
while(n>10){
m=m*10+n%10;
n=n/10;
}
return m;
}
int main(){
long int n;
scanf("%ld",&n);
/***********found***************/
if(fun(n))
printf("%ld是回文数",n);
else
printf("%ld不是回文数",n);
return 0;
}
分析
- 第一处:
- 参数类型:根据
程序第13行
及程序第16行
判断参数的数据类型为long int
- 参数:根据
程序第16行
推测函数调用的参数即为所要判断的数,再根据fun
函数定义中,程序第四行
判断该参数不可能为m
(不可能传参后直接把其再次定义为0),再根据程序第六行
出现的n
直接确定了参数即为n
/***********found***************/
long int fun(long int n){
- 第二处:
- 根据题目对完数的定义:一个正整数,如果正反顺序都表示同一个数,这个整数也可以作为回文数,因此判断分支式子应为
n>0
/***********found***************/
while(n>0){
- 循环体:
while(n>0){
m=m*10+n%10;
n=n/10;
}
讲解:从个位开始,将要判断的数的每一位上的数提取出来(看不懂的可以先看后边"涉及知识点"的讲解),依次移到高位,组建出来新的数m
(简单理解即将原来的数倒过来,如123
经过循环会得到321
)
- 第三处:
根据上边的分析,fun
函数用于判断是否是回文数,如果数字<=0
,直接判断为非回文(可参考后边的"涉及知识点"),如果>0
,则将该数倒过来存入m
进行返回,故f(n)
就是m
,即n
的倒置(如f(123)=321
),如果倒置后等于原来的数,那就说明其是回文数
/***********found***************/
if(fun(n)==n)
改正后的程序
#include<stdio.h>
/***********found***************/
long int fun(long int n){
int m=0;
/***********found***************/
while(n>0){
m=m*10+n%10;
n=n/10;
}
return m;
}
int main(){
long int n;
scanf("%ld",&n);
/***********found***************/
if(fun(n)==n)
printf("%ld是回文数",n);
else
printf("%ld不是回文数",n);
return 0;
}
涉及知识点:
回文数判断
数学上,回文数的定义通常限定为正整数,但根据数学定义和权威解析,0满足正反读相同的条件,且被明确归类为回文数的特殊情形
x%10
任何一个数除以10的余数就是该数最后一位;
x/10
任何一个数除以10的商就是排除掉最后一位后的数;
所以 ,一个数123 就可以通过这种方法得到 12 和 3;
接下来对 12 进行同样的操作,就得到 1 和 2;
接着得到 0 和 1;
整个过程是个循环,当商不是 0 的时候就一直如此;
每次拿到一个余数,都用来构造新数,新数=新数*10+余数;
所以经过三次循环后,我们得到新数 321 ,如果是回文,那么新数应该等于原数,否则,说明不是回文。
数据类型匹配