1943 Problem C:进制转换

题目描述

将一个长度最多为30位数字的十进制非负整数转换为二进制数输出。

输入

多组数据,每行为一个长度不超过30位的十进制非负整数。
(注意是10进制数字的个数可能有30个,而非30bits的整数)

输出

每行输出对应的二进制数。

样例输入

985
211
1126

样例输出

1111011001
11010011
10001100110

思路:

本题中数字可能达到30位,远超于longlong型,所以只能用字符串对数字进行存储;

模拟十进制转二进制的手算过程,不断除基取余;

代码如下:

#include <cstdio>
#include <cstring>
 
char n[200], ans[200]; 
int num[200];

int main()
{
	while (scanf ("%s", n) != EOF) {
		int len = strlen (n);
		for (int i = 0; i < len; i++) {				//将字符转化为数字; 
			num[i] = n[i] - '0';
		}
		
		int carry, count = 0, j = 0;
		while (j < len) {
			ans[count++] = num[len - 1] % 2 + '0'; 			//通过最后一位值确定输出1还是0; 
			
			for (int i = j, carry = 0; i < len; i++) {
				int sum = (carry * 10 + num[i]) / 2;		//模拟进行除法; 
				carry = num[i] % 2;							//判断除2是否除尽; 
				num[i] = sum;
			}
			if (num[j] == 0)          j++;                           //最高位数字为0,下移一位;
		}
		
		for (int i = count - 1; i >= 0; i--) {				//数组从高位输出; 
			printf ("%c", ans[i]);
		}
		printf ("\n");
	}
	
 	return 0;
}   

关键点:

    for (int i = j, carry = 0; i < len; i++) {
		int sum = (carry * 10 + num[i]) / 2;		//模拟进行除法; 
		carry = num[i] % 2;				//判断除2是否除尽; 
		num[i] = sum;
	}
这道题目看了很久的代码才看懂,写一下自己的理解:

这段代码模拟除法从高位开始除2,当除不尽时,乘十加上下一位的值。

因为是用字符串存储,一个位置只存储了一位数字,所以用一个循环处理所有数字;

如若不理解可先手写一十进制数进行2进制的转换。


从这题学到while(~scanf ("%s", n)) 与 while(scanf ("%s", n) != EOF)等价;

scanf函数的返回值就为其成功读入的参数的个数,当读取文件到文件末尾导致无法读取时,函数会返回-1,C语言中EOF来代表-1;

 ~是取反,-1的补码为1111 1111 1111 1111,所以取反后正好为0,所以两种写法等价;

猜你喜欢

转载自blog.csdn.net/privilage/article/details/79961809