題目描述:
將一個長度最多爲30位數字的十進制非負整數轉換爲二進制數輸出。
輸入:
多組數據,每行爲一個長度不超過30位的十進制非負整數。
(注意是10進制數字的個數可能有30個,而非30bits的整數)
輸出:
每行輸出對應的二進制數。
樣例輸入:
0
1
3
8
樣例輸出:
0
1
11
1000
來源:
2008年北京大學軟件所計算機研究生機試真題
解題心得
本題有幾處需要反覆複習留意的地方,在寫其他算法題目時也要格外注意
- 變量清空:在循環體外定義的變量使用時要格外小心,在循環處理數據時變量的值是該留還是該清,只有弄清楚了才能寫出正確的程序,代碼中while循環的idx1和last就進行了清零操作
- c語言中的char數組賦值:對char數組按下標賦值時會出現字符串無意義的問題,對char某個索引直接賦值時又打印不出來。這是由於字符數組中默認以’\0’結尾,打印時讀到’\0’就會結束。而直接賦值又使得字符數組沒有結尾,也就沒有意義。因此在賦值之後補上’\0’即可
//大數進制轉換
#include<stdio.h>
#include<string.h>
using namespace std;
void divide(char str[])
{
char *res = str;//字符串每次除2後的結果
char ans[100];//每次餘數作爲二進制
int idx1 = 0, idx2 = 0;//分別統計res和ans
int last = 0, sum = -1;
while (sum != 0)
{
idx1 = 0;
last = 0;
int len = strlen(res);
for (int i = 0; i < len; i++)
{
int tmp = last * 10 + res[i] - '0';
last = tmp % 2;
res[idx1++] = tmp / 2 + '0';
}
last == 0 ? ans[idx2++] = '0' : ans[idx2++] = '1';
ans[idx2] = '\0';
sum = 0;
for (int i = 0; i < idx1; i++)
{
sum = sum * 10 + (res[i] - '0');
}
}
char *rev_ans = strrev(ans);
for (int i = 0; i < strlen(rev_ans); i++)
{
printf("%c", rev_ans[i]);
}
}
int main()
{
char d[100];
while (gets(d))
{
divide(d);
getchar();//讀取換行符
}
return 0;
}
當然代碼中可能還會有一些bug或者可以優化的地方,歡迎大家在評論區指出,我們一起討論,互相學習!