超大数据10进制转2进制详解(可推广到其他进制)/ Codeup 100000579 问题 C: 进制转换

问题C:进制转换

时间限制 内存限制
1.000sec 32MB

题目描述:

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

输入:

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

输出:

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

样例输入:
	985
	211
	1126
样例输出:
	1111011001
	11010011
	10001100110

分析:
    首先我们知道:一般的整数的取值范围如下:

类型 取值范围
int && long -2147483648 ~ +2147483647
long long -9223372036854775808 ~ +9223372036854775807

    1.对于无符号型的整数,在原有的正的取值范围基础上扩大一倍即可。因此我们没法直接用整形变量来储存题目中给的数据。所以在此我们采用 数组 的形式来储存数据(先用char 类型数组读入数据,然后将数据对应转换到int型数组中,然后处理int 型数组即可):

    2.对于 int 型数组中的数据我们要怎么处理才能将其转变为二进制的呢?我们来看一个例子:
在这里插入图片描述
    3.显然上图就是我们对于已知的十进制数字转换成二进制的过程,结果倒序输出:50对应的二进制数即为 110010;现在对于这道题目来说,我们将数值存在了数组中那么50在数组中的形式为:{5 , 0}。我们没法用直接除的方法来解决。但我们可以这样来思考:
        3.1 因为我们十进制转二进制,对数值进行处理的过程大概如下:


50 % 2 = 0;然后将0记下,并将操作的数据除以250 / 2 = 25;
再:25 % 2 = 1;将1记下,将操作的数字除以225 / 2 = 12......
直到操作数等于0的时候停止,倒序输出记下的数就是我们求的二进制的数。

        3.2 显然,在这个过程中,需要知道的数据就是我们的:操作数转换的进制数每一轮的余数 。因为被操作数每一轮发生一次变化,并且每次操作后就变小,所以,我们可以用原来操作数占用的数组空间来储存变化后的操作数(50 变为 25 再变为 12 …我们只需改变数组中的值即可),我们都用数组 num_int 来表示
        3.3 要转换的进制数显然是2,那么每一轮的余数怎么算?。这里就需要回到我们小学三年级学的除法上了(竖式计算除法),哈哈:

              3.3.1 我们要计算 12 9 10 129_{10} 的二进制数:

首先:
	取出最高项1作为被除数,除以二显然不够除,我们写0在商上面。
然后:
	将2拉下来,这样我们的被除数就变为了1 × 10 + 2 = 12,接着用被除数除以212 ÷ 2 = 6,所以将6写在商0的后面。我们的商就变为了 06;被除数变为了 12 % 2 = 0;
最后:
	将最后一项9拉下来作为被除数,被除数变为0 * 10 + 9 = 9,接着9/2 = 4;余下1,将4写在商的位置,我们的商就是064 , 余数是1;
	我们得到:129 ÷ 2 = 64 ······ 1
	我们下轮用到的就是商 64 ,对64 做相同的处理,那么余数1,会被记住 , 继续处理商64.....直到商变为0为止 , 按顺序记录下所有的余数,最后倒序输出所有的余数就是我们要的结果。


过程如下图(字体不好,哈哈):

在这里插入图片描述


        显然,我们可以看出,每次处理完一位数字后,我们都会用到上一次剩余的结果 temp_before, 并将 temp_before ×10 + 这次要处理的那一位数字 (上图的 1 × 10 + 2 和 0 × 10 + 9就是这个道理),现在我们就明白了:

	处理int型数组中的数字,和小学除法一样,我们要先从最高位开始 逐位处理!

所以,我们需要一个整形变量,temp 从最高位开始来储存每一位上的数字,需要一个整型变量 temp_before 来储存上次操作后的(模除)结果,进行一下循环即可。

while((num_int数组非零)){
	int temp_before = 0;	//刚开始“上一步”剩余的数是0;
	for(int i = 0 ; i < num_int数组的长度 ; i++){
		int temp = (num_int[i] + 10 * temp_before);
		num_int[i] = (num_int[i] + 10 * temp_before) / 2;
		temp_before = temp % 2;	//这一次模除的值(余数)留给下一次处理。
	}
	可以将余数temp_before储存到新整形数组中或者一个堆栈中。
	数组中最后倒序输出,堆栈中最后出栈即可。
	因为此题目中的 模除2  的余数,肯定只能取 01 ,所以两种方法都可以。
}


AC代码如下:

#include<bits/stdc++.h>

using namespace std;

int isEmpty(int num[] , int length){
	for(int i = 0 ; i < length ; i++){
		if(num[i] != 0)
			return 0;	//返回0代表有非零值。 
	}
	return 1;			//返回1代表所有的数据处理好了 
}

int main(){
	int result[200] , count = 0;	//存放余数(结果),count 来计结果数目	
	int num_int[31];	//存放系统给出的数据
	char num_char[31]; 	//接受输入数据
	
	while(scanf("%s" , num_char) != EOF){
		count = 0;		//对于一个新数,count要清零。 
		int length = strlen(num_char);	//存放输入的数字个数 
		for(int i = 0 ; i < length ; i++){
			num_int[i] = num_char[i] - '0';		//将char类型的数据改为int类型的 
		}
		if(isEmpty(num_int , length) == 1){
			printf("0");	//对于输入全为0的处理,直接输出0就好
		}
		while(isEmpty(num_int , length) == 0){	//不全为空,就是没处理好 ,继续处理 
			int temp_before = 0;	//刚开始“上一步”剩余的数是0;
			for(int i = 0 ; i < length; i++){
				int temp = (num_int[i] + 10 * temp_before);
				num_int[i] = (num_int[i] + 10 * temp_before) / 2;
				temp_before = temp % 2;	//这一次模除的值(余数)留给下一次处理。
			}
			result[count++] = temp_before; 
		}
		for(int i = count - 1 ; i > -1 ; i--){
			printf("%d" , result[i]);
		}
		printf("\n");
	}
}


表达不太好,感谢阅读。

发布了12 篇原创文章 · 获赞 17 · 访问量 8477

猜你喜欢

转载自blog.csdn.net/qq_31747473/article/details/104851881
今日推荐