日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

淺談大數(shù)的進(jìn)制轉(zhuǎn)換

 herowuking 2015-06-14

在數(shù)據(jù)結(jié)構(gòu)課關(guān)于棧的這一章中,我們都學(xué)過用“模2取余法”來將一個10進(jìn)制數(shù)轉(zhuǎn)換為一個二進(jìn)制數(shù),進(jìn)而可以推廣到“模n取余法”,經(jīng)其轉(zhuǎn)換為n進(jìn)制(n任意指定)。

確實(shí),這是一個很基礎(chǔ)的題目,可你是否想過如果這個10進(jìn)制數(shù)是一個大數(shù)(其位數(shù)可能上千位,此時用一般數(shù)據(jù)類型肯定是會溢出的),那么這個問題又如何來求解呢?

當(dāng)然,也許你會說很簡單嘛,自己寫一個大數(shù)類(當(dāng)然至少要寫一個大數(shù)除法才行),或者你用的是Java這種現(xiàn)代化語言,就更輕松了,直接用BigInteger這樣的大數(shù)類就可以來表示一個大數(shù),進(jìn)而用書上教的方法來實(shí)現(xiàn)。

但是,真的需要用到大數(shù)類嗎?事實(shí)上,“殺雞焉用牛刀“,我們在紙上模擬一番上述運(yùn)算后就可以發(fā)現(xiàn),只要做一些小小的改進(jìn),就可以在不使用大數(shù)的情況下,也可以通過“模n

取余”的原理來實(shí)現(xiàn)大數(shù)的進(jìn)制轉(zhuǎn)換的。(當(dāng)然,整體的思想仍然是“模n取余”原理?。。。?。

舉個簡單的例子,就比如說把10進(jìn)制數(shù)12轉(zhuǎn)換為2進(jìn)制形式,書上的方法可以用下圖來表示


按照 “先余為低位,后余為高位“這條鐵律,其結(jié)果為1100.

這是書上教我們的常規(guī)思路(可惜按這個的話,大數(shù)是沒法考慮的,因?yàn)榧偃邕@里不是12,而是一個1000位的大數(shù),由于是是對大數(shù)的整體進(jìn)行取余運(yùn)算,不使用大數(shù)類及其

除法操作,又如何得以進(jìn)行呢?),可我們的目的是不使用大數(shù)類,那么現(xiàn)在我們就來換一個視角來看這個問題,12是一個十位數(shù),十位上是1,個位上是2,按照我們正常的

思維來看,這個計(jì)算應(yīng)該是下面這樣的:


那么我們發(fā)現(xiàn)在第一輪運(yùn)算時,十位上的1作為被除數(shù),2作為除數(shù),得到的商是0,余數(shù)是1(可以斷言只考慮當(dāng)前這一個數(shù)位的計(jì)算,余數(shù)或是0,或是1,若是1的話,則進(jìn)

下一數(shù)位(這里即對個位進(jìn)行運(yùn)算)時,要用1乘上進(jìn)制(這里是10)再加上下一個數(shù)位上的值(這里是2)),即得到運(yùn)算進(jìn)入個位時被除數(shù)是12,除數(shù)是2,得到的商是6,

數(shù)是0。第一輪運(yùn)算的結(jié)果是商是06,余數(shù)是0.

進(jìn)入第二輪運(yùn)算,則上一輪的商6(這里首先要去掉前面多余的0)變成本輪的被除數(shù),如此下去,即可得到每輪的余數(shù)。

推廣開來,如果被除數(shù)是一個1000位的大數(shù),例如“12343435154324123……342314324343”

那么我們照樣可以從第一個數(shù)位開始逐位考慮,比如第一位是1(作為被除數(shù)),2是除數(shù),得到的商是0,余數(shù)是1,然后是第二個數(shù)位2,由于上一位留下了余數(shù)1,則此時被

除數(shù)應(yīng)該是1*10+2 = 12,所以得到的商是6,余數(shù)是0,即運(yùn)算到此時的商是06,然后是第三個數(shù)位3,由于上一個數(shù)位留下的余數(shù)是0,所以此時被除數(shù)就是3,。。。如此下去

就完成第一輪的運(yùn)算,這一輪完畢后,需要把得到的商變成下一輪的被除數(shù),繼續(xù)上述的運(yùn)算,直到被除數(shù)為0才停止。

下面給出了一個示例代碼,展示了如何將一個10進(jìn)制的大數(shù)轉(zhuǎn)換為其二進(jìn)制形式,僅供參考:

  1. #include <stdio.h>  
  2. #include <string.h>  
  3.   
  4. char str[1000];//輸入字符串  
  5. int start[1000],ans[1000],res[1000]; //被除數(shù),商,余數(shù)  
  6.   
  7. //轉(zhuǎn)換前后的進(jìn)制  
  8. const int oldBase = 10;  
  9. const int newBase = 2;  
  10.   
  11. void change()  
  12. {//各個數(shù)位還原為數(shù)字形式  
  13.     int i,len = strlen(str);  
  14.     start[0] = len;  
  15.     for(i=1;i<= len;i++)  
  16.     {  
  17.         if(str[i-1] >= '0' && str[i-1] <= '9')  
  18.         {  
  19.             start[i] = str[i-1] - '0';  
  20.         }  
  21.     }   
  22. }  
  23.   
  24. void solve()  
  25. {  
  26.     memset(res,0,sizeof(res));//余數(shù)初始化為空  
  27.     int y,i,j;  
  28.     //模n取余法,(總體規(guī)律是先余為低位,后余為高位)  
  29.     while(start[0] >= 1)  
  30.     {//只要被除數(shù)仍然大于等于1,那就繼續(xù)“模2取余”  
  31.         y=0;  
  32.         i=1;  
  33.         ans[0]=start[0];  
  34.         //  
  35.         while(i <= start[0])  
  36.         {  
  37.             y = y * oldBase + start[i];  
  38.             ans[i++] = y/newBase;  
  39.             y %= newBase;   
  40.         }  
  41.         res[++res[0]] = y;//這一輪運(yùn)算得到的余數(shù)  
  42.         i = 1;  
  43.         //找到下一輪商的起始處  
  44.         while((i<=ans[0]) && (ans[i]==0)) i++;  
  45.         //清除這一輪使用的被除數(shù)  
  46.         memset(start,0,sizeof(start));  
  47.         //本輪得到的商變?yōu)橄乱惠喌谋怀龜?shù)  
  48.         for(j = i;j <= ans[0];j++)  
  49.             start[++start[0]] = ans[j];   
  50.         memset(ans,0,sizeof(ans)); //清除這一輪的商,為下一輪運(yùn)算做準(zhǔn)備  
  51.     }   
  52. }  
  53.   
  54. void output()  
  55. {//從高位到低位逆序輸出  
  56.     int i;  
  57.     for(i = res[0];i >= 1;--i)  
  58.     {    
  59.         printf("%d",res[i]);  
  60.     }  
  61.     printf("\n");   
  62. }  
  63.   
  64. int main()  
  65. {  
  66.     scanf("%s",str);  
  67.     change();  
  68.     solve();  
  69.     output();  
  70.     return 0;  
  71. }  

高精度進(jìn)制轉(zhuǎn)換模版:

  1. /* 
  2. 高精度進(jìn)制轉(zhuǎn)換  
  3. 把oldBase 進(jìn)制的數(shù)轉(zhuǎn)化為newBase 進(jìn)制的數(shù)輸出。 
  4. 調(diào)用方法,輸入str, oldBase newBase. 
  5. change(); 
  6. solve(); 
  7. output(); 
  8. 也可以修改output(),使符合要求,或者存入另外一個字符數(shù)組,備用  
  9. */  
  10. #include<stdio.h>  
  11. #include<string.h>  
  12. #defien MAXSIZE 1000  
  13. char str[MAXSIZE];//輸入字符串  
  14. int start[MAXSIZE],ans[MAXSIZE],res[MAXSIZE];//被除數(shù),商,余數(shù)  
  15. int oleBasw,newBase;//轉(zhuǎn)換前后的進(jìn)制  
  16.   
  17. //單個字符得到數(shù)字  
  18. int getNum(char c)//這里進(jìn)制字符是先數(shù)字,后大寫字母,后小寫字母的   
  19. {  
  20.     if(c>='0'&&c<='9') return c-'0';//數(shù)字   
  21.     if(c>='A'&&c>='Z') return c-'A'+10;//大寫字母   
  22.     return c-'a'+36;//小寫字母   
  23. }      
  24. //數(shù)字得到字符  
  25. char getChar(int i)  
  26. {  
  27.     if(i>=0&&i<=9)return i+'0';  
  28.     if(i>=10&&i<=35)return i-'10'+'A';  
  29.     return i-36+'a';  
  30. }       
  31. void change()//把輸入的字符串的各個數(shù)位還原為數(shù)字形式  
  32. {  
  33.     int i;  
  34.     start[0]=strlen(str);//數(shù)組的0位存的是數(shù)組長度  
  35.     for(i=1;i<=start[0];i++)  
  36.         start[i]=getNum(str[i-1]);   
  37. }      
  38. void solve()  
  39. {  
  40.     memset(res,0,sizeof(res));//余數(shù)位初始化為空  
  41.     int y,i,j;  
  42.     while(start[0]>=1)   
  43.     {  
  44.         y=0;i=1;  
  45.         ans[0]=start[0];  
  46.         while(i<=start[0])  
  47.         {  
  48.             y=y*oldBase+start[i];  
  49.             ans[i++]=y/newBase;  
  50.             y%=newBase;  
  51.         }      
  52.         res[++res[0]]=y;//這一輪得到的余數(shù)  
  53.         i=1;//找下一輪商的起始處,去掉前面的0  
  54.         while(i<=ans[0]&&ans[i]==0) i++;  
  55.         memset(start,0,sizeof(start));  
  56.         for(j=i;j<ans[0];j++)  
  57.            start[++start[0]]=ans[j];  
  58.         memset(ans,0,sizeof(ans));   
  59.     }      
  60. }    
  61. void output()//從高位到低位逆序輸出   
  62. {  
  63.     int i;  
  64.     for(i=res[0];i>=1;i--)  
  65.         printf("%d",getChar(res[i]));  
  66.     printf("\n");  
  67. }  

如果你對這個話題感興趣的話,可以用這個思路來嘗試解決下PKU 1220這個題目:http://acm.pku.edu.cn/JudgeOnline/problem?id=

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多