整数分解5.3.2

前面写过逆序的

最后一个数后面不要有空格

复制代码
#include <stdio.h>

int main()
{
	int x;
	scanf("%d",&x);
	int d;
	do{
	   d=x%10;
	   printf("%d",d);
	   if(x>=10){
	   	printf(" ");
	   }
	   x/=10;
	}while(x>0);
	printf("\n");
	return 0;
}

现在这个是逆序的

x%10如果到只剩个位时 后面再取余就等于0了所以是最后一位 这时用if语句限制这个条件就可以做到最后一个数后面没有空格。

把他正序思路也很简单,就是先给他逆序过去 再逆序过来 逆逆得正

复制代码
#include <stdio.h>

int main()
{
	int x;
	scanf("%d",&x);
	int t=0;
	do{
	    int d=x%10;
		t=t*10+d;
		x/=10;
	}while(x>0);
	printf("x=%d,t=%d\n", x, t);
	x=t;
	do{
	   int d=x%10;
	   printf("%d",d);
	   if(x>=10){
	   	printf(" ");
	   }
	   x/=10;
	}while(x>0);
	printf("\n");
	return 0;
}

但这种逆序两次的方法不能适用于末位数为零的数字

如果末位为零就会这样 就得换种方法 太难了 不会。。。。。

复制代码
#include <stdio.h>

int main()
{
	int x;
	scanf("%d", &x);
	
	int mask = 1;
	int t = x;
	while(t>9){
		t /= 10;
		mask *=10;
	}
	printf("x=%d, mask=%d\n", x, mask);
	do {
		int d = x / mask;
		printf("%d", d);
		if (mask>9){
			printf(" ");
		}
		x %= mask;
		mask /=10;
	}while( mask > 0 );
	printf("\n");
	return 0;
}

这个就是最终改进的 下面一步一步来理解

复制代码
    思路

1  x=12345
2  12345/10000  ->1
3  12345%10000  ->2345
4  10000/10     ->1000
5  2345/1000    ->2
6  2345%1000    ->345
7  1000/10      ->100
8  345/100      ->3
9  345%100      ->45
10 100/10       ->10
11 45/10        ->4
12 45%10        ->5
13 10/10        ->1
14 5/1          ->5
15 5%1          ->0
16 1/10         ->0
 此时第 2,5,8,11,14行的就是要求的结果

这就是一个循环 输出那几行的数就是答案

复制代码
#include <stdio.h>

int main()
{
	int x;
//	scanf("%d", &x);
	x=12345;
	int mask=10000;
	do{
		int d = x / mask;
		x %= mask;
		mask /=10;
		printf("x=%d,mask=%d,d=%d\n", x, mask, d);
	}while(x>0);
	printf("\n");
	return 0;
}

这是第一步 求出每一位的数字 d就是要求的结果

但这个写法是错误的对一些边界就不能用了 上面这个写法是错的

复制代码
错误原因

以70000为例    
70000/10000   ->7
70000%10000   ->0
这里第二个数就是0了下面就没法再算了
而while的条件是x>0   这时候就直接输出了
但这时候mask它并不是零   等到mask为零的时候就对了所以要把while的条件改为mask>0;

就会得到这样的答案。

这就是改过之后的结果 是符合的

下一步

复制代码
#include <stdio.h>

int main()
{
	int x;
//	scanf("%d", &x);
	x=70000;
	int mask=10000;
	do{
		int d = x / mask;
		printf("%d", d);
		if(mask>0){
			printf(" ");
		}
		x %= mask;
		mask /=10;
	//	printf("x=%d,mask=%d,d=%d\n", x, mask, d);
	}while(mask>0);
	printf("\n");
	return 0;
}

里面加了一个加空格的if语句 if语句的条件也和上面的那个一样 如果还是x>0的话那就只有第一个数后面有空格 这样就错了

下一步

现在程序的mask是一个固定的数值 输入的x不是固定的可以是任意位数 mask对应几位数就要为该位数的最小数10 100 1000.... 这时候就要找一个能根据x的不同让mask与他保持同位数的方法

计算整数的位数

复制代码
#include <stdio.h>

int main()
{
	int x;
//	scanf("%d", &x);
	x=70010;
	int cnt = 0;
	do{
		x/=10;
		cnt++;
	}while(x>0);
		printf("cnt=%d\n", cnt);
		int mask = 10000;
	do{
		int d = x / mask;
		printf("%d", d);
		if(mask>0){
			printf(" ");
		}
		x %= mask;
		mask /=10;
	//	printf("x=%d,mask=%d,d=%d\n", x, mask, d);
	}while(mask>0);
	printf("\n");
	return 0;
}
复制代码
理解


加入一个变量cnt   让他来表示位数
让x/=10来一次次减少他的位数  然后累加cnt就得到了x是几位数

表示mask 可以引入pow函数 但不建议用 #include <math.h>

pow

还没学

另外一种方法 思路清晰简单 就是让初始变量mask=1;然后让它加到上面那个算几位数的循环里

让他每循环一次乘于一次10就好了,

复制代码
#include <stdio.h>

int main()
{
	int x;	scanf("%d", &x);
//	x=70010;
	int cnt = 0;
	int mask = 1;
	do{
		x/=10;
		mask *=10;
	}while(x>0);
		printf("mask=%d\n", mask);
//	int mask = 10000;
	do{
		int d = x / mask;
		printf("%d", d);
		if(mask>0){
			printf(" ");
		}
		x %= mask;
		mask /=10;
	//	printf("x=%d,mask=%d,d=%d\n", x, mask, d);
	}while(mask>0);
	printf("\n");
	return 0;
}

就是上面这样 然后你会发现它多了一个0 .。。。。。。。。。。。。。。。。。。。

这样也是错的。。。。。。。。。。。。。。。 可以在循环后面给mask除去一个10 .。。/。。/

也可以把这个循环里面的条件x>0改为x>9这样是应为它一直除到只剩个位数的时候结果就小了不满足循环条件了 就少了一遍循环 位数就对了 但这种方法不能以偏概全 这种错误的由来自do-while循环本身的·特性 他是先执行一遍再判断循环 所以多了

这时候就要换while循环

复制代码
#include <stdio.h>

int main()
{
	int x;	scanf("%d", &x);
//	x=70010;
	int mask = 1;
	while(x>9){
		x /= 10;
		mask *=10;
	}
		printf("mask=%d\n", mask);
//	int mask = 10000;
	do{
		int d = x / mask;
		printf("%d", d);
		if(mask>0){
			printf(" ");
		}
		x %= mask;
		mask /=10;
	//	printf("x=%d,mask=%d,d=%d\n", x, mask, d);
	}while(mask>0);
	printf("\n");
	return 0;
}

这时候mask的值就能确保是正确的 但你发现 下面输出的结果已经错很久了

原因 在上面第一个循环输出x的值

你会发现此时的x的值已经被替换了,所以还要引入一个变量让他等于x 让这个新引入的变量代替第一个循环体中的x

复制代码
#include <stdio.h>

int main()
{
	int x;	scanf("%d", &x);
//	x=70010;
	int mask = 1;
	int t = x;
	while(t>9){
		t /= 10;
		mask *=10;
	}
		printf("t=%d,mask=%d\n", t, mask);
//	int mask = 10000;
	do{
		int d = x / mask;
		printf("%d", d);
		if(mask>0){
			printf(" ");
		}
		x %= mask;
		mask /=10;
	//	printf("x=%d,mask=%d,d=%d\n", x, mask, d);
	}while(mask>0);
	printf("\n");
	return 0;
}

至此 所有的问题就都解决了

最后再优化一下

复制代码
#include <stdio.h>

int main()
{
	int x;	scanf("%d", &x);
	int mask = 1;
	int t = x;
	while(t>9){
		t /= 10;
		mask *=10;
	}
	do{
		int d = x / mask;
		printf("%d", d);
		if(mask>0){
			printf(" ");
		}
		x %= mask;
		mask /=10;
	}while(mask>0);
	printf("\n");
	
	return 0;
}

很多细节很重要 比如循环条件的选择 对一些语句特性的理解 某些多次要运用的变量在哪里被用过之后数额是否发生变化

最重要的是思维

相关推荐
江畔柳前堤6 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Forever Nore7 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考8 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX9 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面10 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号10 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽10 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI10 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
地平线开发者12 小时前
征程6工具链模型X86推理方式说明
算法
地平线开发者12 小时前
【征程6】校准量化中HistogramObserver解析
算法