【C语言及程序设计】项目1-11-1&2:(分离)各位数& 整数部分与小数部分

这篇博客介绍了C语言中分离数字各位数和整数小数部分的方法。项目1-11-1通过对10的幂次取余来实现分离各位数;项目1-11-2则利用数据类型的隐性转换,讨论了两种不同的处理方式,方案1直接舍去小数部分,方案2实现了四舍五入的效果。
项目1-11-1:分离各位数
/* 分离各位数.cpp: 
问题描述:写一个程序,输入x(三位数),输出其个、十、百位数,用空格隔开
样例输入:768
样例输出:8 6 7
*/

#include "stdafx.h"

int main()
{
	int n, m;
	scanf_s("%d",&n);

	do
	{
		m = n % 10;
		printf("%d", m);

		n = n / 10;

	} while (n != 0);
    
	return 0;
}

感想:

最经典的module之一,对10^n取余,可以从数值中,取出n位以下的位数(含n位);

分离各位数就是基于这个方法,然而(任意位数的数值)分离各位数,如何实现正序(原序)排列呢?


项目1-11-2:分离整数部分与小数部分
/* 分离整数和小数部分.cpp: 
问题描述:编写一个程序,其功能为:从键盘上输入一个浮点数(小数点后有三位数),然后分别输出该数的整数部分和小数部分。
样例输入:123.456
样例输出:123 456
*/

#include "stdafx.h"


int main()
{
	float f;
	int n, m, l(0);
	scanf_s("%f", &f);
	n = f;
	
	l = (f * 1000);
	m = l % 1000;
	//方案2:m = (int)(f * 1000) % 1000;
	//方案1:m = 1000 * (f - n);

	printf("%d %d", n, m);

	return 0;
}

感想:

这道题的求解主要利用,项目1-

<think>嗯,用户需要的是一个C语言程序,输入一个三位正整数,然后输出由这三个字组成的最大小数。比如输入213,输出最大321,最小123。首先,我得想怎么分解这个三位的各个位上的字。三位的话,可以用除法取余来获取百位、十位、个位。比如,假设输入的是n,那么百位是n/100,十位是(n/10)%10,个位是n%10。这样就能得到三个字了。 接下来,需要将这三个字排列组合,找出所有可能的三位,然后比较大小得到最大值最小值。不过,直接生成所有排列可能比较麻烦,有没有更高效的方法呢?比如,可以先将这三个字按从大到小排序,然后组合成最大;按从小到大排序,组合成最小数。这样就不用生成所有排列了,节省时间。 排序的话,可以用冒泡排序或者简单的比较交换。比如,三个a、b、c,先比较ab,把大的放前面,再比较bc,把大的放中间,最后可能还需要再调整ab的位置,确保顺序正确。或者使用组来存储三个字,然后进行排序。比如,把三个字存到组里,然后用选择排序或者冒泡排序来排列。 比如,假设百位是h,十位是t,个位是d。那么,将这三个字存入组arr[3] = {h, t, d},然后对组进行降序排序,得到最大就是arr[0]*100 + arr[1]*10 + arr[2]。升序排序的话,最小数就是arr[0]*100 + arr[1]*10 + arr[2],不过要注意如果最小的前面有0的情况,但题目输入是三位正整数,所以分解出来的三个字都不为0吗?不一定哦,比如输入100,分解后是1,0,0,这时最小数应该是001,但实际三位的话应该是100?或者题目是否允许有前导零?不过示例中的输入213输出的是123,说明最小数可能是三位,不管是否有前导零,但实际三位的前导零会被忽略吗?比如输入100,最大100,最小数也是100?或者可能用户希望输出的最小数是001?但根据示例,213的最小数123,所以应该把三个字按升序排列后组成三位,前面的零会被保留吗?比如输入102,分解为1、0、2,升序排序后是0、12,那么最小数应该是012,即12,但三位的话可能需要补零。但根据用户需求,输入的是三位正整数,输出的应该也是三位,所以可能需要处理这种情况。比如,当最小的字是0时,比如输入是102,那么升序排列后的顺序是0、12,但是作为三位的最小值应该是102?或者按照排列组合的最小值,比如01212,但可能用户希望输出三位,所以需要确保最小数是三位,这时候可能需要将最小的非零放在百位,剩下的按升序排列。这可能比较复杂。不过根据示例,输入213,分解为21、3,升序排列后是12、3,所以最小数123,这说明用户期望的是将三个字按升序排列后的组合,不管是否有前导零。所以在这种情况下,如果输入的是102,分解后的字是1、0、2,那么升序排列是0、12,最小数应该是012,即12,但用户可能需要三位,所以可能输出012,但实际输出时会变成12,因为前导零被忽略了。这可能需要进一步确认。不过根据用户给出的示例,输出是三位,所以可能输入的三位不会有零的情况,或者用户希望无论是否有零,都输出三位,比如如果输入是100,那么最大是100,最小也是100。或者可能题目保证输入的三位各位字不全相同,但不确定。所以可能需要按原样处理,即不管是否有零,都按升序排列后的结果组合成三位,比如0放在百位的话,实际值会变成两位,但根据用户示例,输入213输出的是123,所以可能程序需要处理这种情况,确保输出的是三位。或者用户可能要求三位的每一位都不为零?需要看问题描述。用户的问题描述是输入三位正整数,所以三位的每一位可能有零,但三位本身不能是零开头。所以当分解后的字中有零时,比如输入是102,那么最大210,最小数是012,即12,但作为三位的话,可能需要补零,或者用户希望输出的是012?但通常三位的前导零会被省略,所以这可能是个问题。不过根据用户提供的示例,输入213输出的是321123,所以当三个字中没有零时,升序排列后直接组合即可。当存在零时,如何处理?比如输入302,分解为3、0、2,升序排列后是0、2、3,最小数应该是023即23,但用户可能需要三位,所以可能需要调整,将第二小的放在百位,然后剩下的按升序排列。这可能需要更复杂的逻辑。比如,找出三个中的最小值,如果是0,则百位不能为0,需要选择次小的作为百位,剩下的按升序排列。例如,输入302的三个字是3、0、2,最小数的构造应该是百位为0的情况不行,所以百位选次小的2?或者可能用户希望的最小数就是三位,允许前导零?这需要明确。但根据示例,用户可能期望的是将三个字按升序排列后的结果,即使有前导零,输出三位,例如023,但输出的时候可能被当作整数23,而前面的零会被忽略。这会导致问题。比如,用C语言输出023的话,printf("%d", 23)会输出23,而不是023。所以,如果用户希望的最小数是一个三位,包含前导零的话,可能需要将结果作为字符串处理,而不是整数。但用户提供的示例输出是123,即三位整数,所以可能用户希望的是将三个字按升序排列后的三位,不考虑前导零的问题,即当三个字中有零时,允许最小数的前导零,但输出时会自动转为整数,导致前导零消失。这可能不符合用户需求。例如,输入302,分解后的字是3、0、2,升序排列后是0、2、3,最小数应该是023,但作为整数输出是23。这可能不是用户想要的。因此,可能需要另一种方法,确保最小数的百位不为零。所以,处理这个问题需要分情况:当三个字中有零时,构造最小数时,百位必须是非零的最小数字,剩下的字按升序排列。例如,输入302,分解为3、0、2,那么最小数的百位应该是0吗?但三位的百位不能是零,所以需要找到最小的非零字作为百位。所以在这种情况下,三个字中的非零最小数2,所以百位是2,然后剩下的03按升序排列,得到203。这样,最小数203。而输入302的话,最大是320,最小数203。这可能更合理。所以,原来的思路可能需要调整,不能简单地对三个字进行升序或降序排列,而是需要考虑百位不能为零的情况。因此,正确的处理步骤应该是: 1. 分解三位的各个位上的字,得到h(百位)、t(十位)、d(个位)。 2. 将这三个字存入组。 3. 构造最大:将三个字按降序排列,组合成三位。 4. 构造最小数:找出三个字中的最小值,如果最小值为0,则找次小值作为百位,剩下的按升序排列。但这样可能比较复杂,或者可以先将三个字按升序排列,然后如果百位是0,则找到第一个非零的百位交换。 或者,构造最大时,直接降序排列,组合即可。构造最小数时,先升序排列,如果第一个字是0,则找到第一个非零的字,第一个位置交换,然后再组合。 例如,三个字是0、2、3,升序排列后是0、2、3,此时百位是0,需要交换第一个非零的字(2)到百位,得到2、0、3,然后组合成203。这样处理的话,就能得到正确的最小数。 所以,具体步骤可能是: - 将三个字存入组,排序升序。 - 如果第一个元素是0,则遍历组找到第一个非零元素,将其第一个元素交换。 - 然后组合成三位作为最小数。 同理,最大就是降序排列后的组合。 现在,如何实现这个逻辑呢?在C语言中,可以用组来存储三个字,然后进行排序。例如,使用选择排序或冒泡排序对组进行升序降序排列。 例如,分解后的字存入组arr,长度为3。最大的构造: - 对arr进行降序排列,得到max_arr,然后max = max_arr[0]*100 + max_arr[1]*10 + max_arr[2]. 最小数的构造: - 对arr进行升序排列,得到min_arr。 - 如果min_arr[0] == 0,则找到第一个非零的位置(比如i从12),找到第一个非零元素,交换到0的位置。 - 然后组合成三位:min = min_arr[0]*100 + min_arr[1]*10 + min_arr[2]. 例如,输入302,分解为3、0、2,升序排序得到0、2、3。然后检查第一个元素是否为0,是的。找到第一个非零的是位置1(元素2),交换位置01,得到2、0、3。组合成203。 另一个例子,输入213,升序排序得到12、3,没有前导零,直接组合成123。 输入100,分解为1、0、0,升序排序得到0、0、1。第一个非零的位置是2,交换位置02,得到1、0、0,组合成100,即正确的最小数。 这样处理的话,就能解决前导零的问题。 那么,在代码中如何实现呢?分解三位为百位、十位、个位: int num; scanf("%d", &num); int h = num / 100; int t = (num / 10) % 10; int d = num % 10; 将这三个存入组: int arr[3] = {h, t, d}; 然后对组进行升序排序: // 升序排序 for (int i = 0; i < 2; i++) { for (int j = i+1; j < 3; j++) { if (arr[i] > arr[j]) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } 然后处理前导零的情况: if (arr[0] == 0) { // 找到第一个非零的位置 int first_non_zero = -1; for (int i = 1; i < 3; i++) { if (arr[i] != 0) { first_non_zero = i; break; } } if (first_non_zero != -1) { // 交换位置0first_non_zero int temp = arr[0]; arr[0] = arr[first_non_zero]; arr[first_non_zero] = temp; } } 然后,最小数就是arr[0]*100 + arr[1]*10 + arr[2]; 同理,对降序排序: // 降序排序 for (int i = 0; i < 2; i++) { for (int j = i+1; j < 3; j++) { if (arr[i] < arr[j]) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } 最大就是arr[0]*100 + arr[1]*10 + arr[2]; 但需要注意,降序排序后不需要处理前导零,因为最大的百位肯定是最大的字,不会为零,因为输入是三位正整数,所以百位原本不为零。 这样,整个程序的逻辑就完成了。现在将这些步骤整合到C语言代码中。 例如,完整的代码: #include <stdio.h> int main() { int num; scanf("%d", &num); int h = num / 100; int t = (num / 10) % 10; int d = num % 10; int arr[3] = {h, t, d}; // 计算最大:降序排列 for (int i = 0; i < 2; i++) { for (int j = i+1; j < 3; j++) { if (arr[i] < arr[j]) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } int max_num = arr[0] * 100 + arr[1] * 10 + arr[2]; // 重新初始化组,因为之前的排序改变了顺序 arr[0] = h; arr[1] = t; arr[2] = d; // 计算最小数:升序排列 for (int i = 0; i < 2; i++) { for (int j = i+1; j < 3; j++) { if (arr[i] > arr[j]) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } // 处理前导零 if (arr[0] == 0) { int first_non_zero = -1; for (int i = 1; i < 3; i++) { if (arr[i] != 0) { first_non_zero = i; break; } } if (first_non_zero != -1) { int temp = arr[0]; arr[0] = arr[first_non_zero]; arr[first_non_zero] = temp; } } int min_num = arr[0] * 100 + arr[1] * 10 + arr[2]; printf("最大:%d\n最小数:%d", max_num, min_num); return 0; } 测试示例: 输入213: 分解得到2,1,3。最大降序排列3,2,1 → 321。最小数升序排列1,2,3 → 123。 输入302: 分解得到3,0,2。最大降序3,2,0 → 320。最小数升序0,2,3 → 处理前导零,找到第一个非零的是位置1,交换得到2,0,3 → 203。 输入100: 分解得到1,0,0。最大降序1,0,0 →100。最小数升序0,0,1 → 处理前导零,找到第一个非零的是位置2,交换得到1,0,0 →100。 输入102: 分解得到1,0,2。最大降序2,1,0 →210。最小数升序0,1,2 → 处理前导零,交换01 →1,0,2 →102。 这样,代码应该能正确处理各种情况。 现在,用户的问题是要输入三位正整数,输出最大最小的三位。所以这个代码应该能满足需求。并且示例中的输入213的输出符合要求。</think>以下是根据您需求设计的C语言程序,实现输入三位正整数并输出最大最小组合: ### 解决方案 ```c #include <stdio.h> int main() { int num; scanf("%d", &num); // 分解各位字 int h = num / 100; // 百位 int t = (num / 10) % 10; // 十位 int d = num % 10; // 个位 // 将字存入组 int arr[3] = {h, t, d}; // 计算最大(降序排列) for (int i = 0; i < 2; i++) { for (int j = i+1; j < 3; j++) { if (arr[i] < arr[j]) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } int max_num = arr[0] * 100 + arr[1] * 10 + arr[2]; // 重置组后计算最小数(升序排列+处理前导零) arr[0] = h; arr[1] = t; arr[2] = d; for (int i = 0; i < 2; i++) { for (int j = i+1; j < 3; j++) { if (arr[i] > arr[j]) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } // 处理前导零 if (arr[0] == 0) { for (int i = 1; i < 3; i++) { if (arr[i] != 0) { int temp = arr[0]; arr[0] = arr[i]; arr[i] = temp; break; } } } int min_num = arr[0] * 100 + arr[1] * 10 + arr[2]; printf("最大:%d\n最小数:%d", max_num, min_num); return 0; } ``` ### 执行示例 输入:213 输出: 最大:321小数123 ### 实现原理 1. **字分解**:通过整除取余运算分离出百位、十位、个位字[^4] 2. **最大计算**:将三个字降序排列后直接组合 3. **最小数计算**: - 先进行升序排列 - 若首位为0,则后续第一个非零字交换位置,避免前导零问题[^2] 4. **组合输出**:将排列后的字按权值相加组合成最终结果 ### 注意事项 - 输入必须为三位正整数 - 当输入字含重复字时(如100),程序仍能正确处理 - 前导零处理逻辑确保最小数始终为有效三位[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值