超大數據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 我們要計算 12910129_{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");
	}
}


表達不太好,感謝閱讀。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章