問題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記下,並將操作的數據除以2:50 / 2 = 25;
再:25 % 2 = 1;將1記下,將操作的數字除以2:25 / 2 = 12;
......
直到操作數等於0的時候停止,倒序輸出記下的數就是我們求的二進制的數。
3.2 顯然,在這個過程中,需要知道的數據就是我們的:操作數 、轉換的進制數 、每一輪的餘數 。因爲被操作數每一輪發生一次變化,並且每次操作後就變小,所以,我們可以用原來操作數佔用的數組空間來儲存變化後的操作數(50 變爲 25 再變爲 12 …我們只需改變數組中的值即可),我們都用數組 num_int 來表示
3.3 要轉換的進制數顯然是2,那麼每一輪的餘數怎麼算?。這裏就需要回到我們小學三年級學的除法上了(豎式計算除法),哈哈:
3.3.1 我們要計算 的二進制數:
首先:
取出最高項1作爲被除數,除以二顯然不夠除,我們寫0在商上面。
然後:
將2拉下來,這樣我們的被除數就變爲了1 × 10 + 2 = 12,接着用被除數除以2:12 ÷ 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 的餘數,肯定只能取 0 或 1 ,所以兩種方法都可以。
}
#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");
}
}