目录
Step1.先学习输入13425,得出5 2 4 3 1的处理
方案一
Step1.先学习输入13425,得出5 2 4 3 1的处理
#include<stdio.h>
int main()
{
int x;
scanf("%d",&x);
int t;
do{
t=x%10;
printf("%d",t);
if(x>9)printf(" ");
x /=10;
}while(x>0);
printf("\n");
return 0;
}
Step2.得出正序分解整数的方案一
输入13425,输出52431后能输出1 3 4 2 5的处理(即先逆序,再逆序):
#include<stdio.h>
int main()
{
int x;
scanf("%d",&x);
x=13425;
int t=0;//t用来构建逆序过来的数
do{
int d=x%10;
t=t*10+d;
x /=10;
}while(x>0);
printf("x=%d,t=%d\n",x,t);
x=t;//为使x还能进行接下来的处理,把
/*d=5,t=5,x=1342
d=2,t=52,x=134;
......
直到d=1,t=52431,x=0时不满足x>0,从而跳出循环*/
do{
int d=x%10;
printf("%d",d);
if(x>9)printf(" ");
x /=10;
}while(x>0);
printf("\n");
return 0;
}
当输入变成700时,最后输出不是700,而是7,因而这种先逆序再逆序的方案只适用于整数末尾没有零的情况。
方案二
step1.给出简单整数的处理方法
#include<stdio.h>
int main()
{
int x;
scanf("%d",&x);
/* 13425/10000--1 1是我们需要提取出来的数
13425%10000--3425 提取完后取余把已提取的数删掉
10000/10-----1000 后续每一轮用去取余的数也要减一位
* 3425/1000----3
3425%1000----425
1000/10------100
* 425/100------4
425%100------25
100/10-------10
* 25/10--------2
25%10--------5
10/10--------1
* 5/1----------5
5%1----------0
1/10---------0 */
int mask=10000;
do{
int d = x / mask;
/*printf("%d",d);
if(x>9){
printf(" ");
} */
x %=mask;
mask /=10;
printf("x=%d,mask=%d,d=%d\n",x,mask,d);
}while(x>0);
return 0;
}
step2.解决整数末尾为零无法分解的问题
当输入值是70000时,发现最后得出的d=7,不成立,原因在于,当整数末尾有零时,x=0时就提前结束循环了,所以只要把while(x>0)和if(x>0)改为(mask>0)即可。此时一开始列的计算就起了作用,在写算法前给出了直观而清晰的数据变化过程,帮助我们确定循环开始和结束的条件。
#include<stdio.h>
int main()
{
int x;
scanf("%d",&x);
/* 13425/10000--1 1是我们需要提取出来的数
13425%10000--3425 提取完后取余把已提取的数删掉
10000/10-----1000 后续每一轮用去取余的数也要减一位
* 3425/1000----3
3425%1000----425
1000/10------100
* 425/100------4
425%100------25
100/10-------10
* 25/10--------2
25%10--------5
10/10--------1
* 5/1----------5
5%1----------0
1/10---------0 */
int mask=10000;
do{
int d = x / mask;
printf("%d",d);
if(mask>9){
printf(" ");
}
x %=mask;
mask /=10;
}while(mask>0);
return 0;
}
Step3.使mask具有普适性
上一步我解决了整数末尾为零不能计算的情形,接下来,要考虑如何使程序自行识别输入数字后得出mask的问题了。
法一
将问题转化成两步,利用循环计算数字位数cnt,再引进pow函数计算出mask的值。具体如下:
#include<stdio.h>
int main()
{
int x;
scanf("%d",&x);
int cnt=0;
do{
x /=10;
cnt++;
}while(x>0);
int mask=pow(10,cnt-1);
printf("%d",mask);
return 0;
}
法二
更简便的方法是,在每一轮x/10的同时,让mask一步步乘上去,如下:
#include<stdio.h>
int main()
{
int x;
scanf("%d",&x);
int mask=1;
do{
x /=10;
mask *=10;
}while(x>0);
printf("mask=%d\n",mask);
return 0;
}
但是不难发现mask总比期望值大十倍,所以我们要让这个循环少跑一轮,将while(x>0)改成(x>9);
如果直接将此计算插入的话,下一个循环要用的x的值已被破坏,所以我们要定义另一个量代替x进行mask的计算。特别注意,这个量必须放在x已被识别后赋值。
int x;
int X=x;
scanf("%d",&x);
上图是错误的!
#include<stdio.h>
int main()
{
int x;
scanf("%d",&x);
int X=x;
int mask=1;
do{
X /=10;
mask *=10;
}while(X>9);
printf("mask=%d\n",mask);
do{
int d = x / mask;
printf("%d",d);
if(mask>9){
printf(" ");
}
x %=mask;
mask /=10;
}while(mask>0);
return 0;
}
法三
进一步提高mask的普适性。
这样就对了吗,我们还要考虑一些边界的情况:如输入1时,我们希望mask=1,而不是10。
这个情况,其实是do while循环的特性导致的,即不管什么条件,都会进行一次循环,我们不妨改用while循环来避免,即只有当x不是一位数时才有必要进入这个循环。如下:
#include<stdio.h>
int main()
{
int x;
scanf("%d",&x);
int X=x;
int mask=1;
while(X>9){
X /=10;
mask *=10;
}
do{
int d = x / mask;
printf("%d",d);
if(mask>9){
printf(" ");
}
x %=mask;
mask /=10;
}while(mask>0);
return 0;
}