利用遞迴解決進製轉換問題

2021-07-11 17:44:43 字數 3442 閱讀 1496

放寒假的時候博主在家學如何程式設計實現十進位制與任意進製之間的轉換,在網上蒐集的了很多種方法,但奈何自己太渣好多都看的雲裡霧裡,而且普遍**都比較長...然而今天博主再看遞迴部分的時候突然發現這道題的**其實可以用遞迴很簡潔的實現,希望對大家能有所幫助。

問題描述:

將十進位制數轉化為任意進製按格式並輸出。

輸入格式:輸入兩個數,第乙個數字需要轉化的十進位制數字,第二個數為要轉成的進製數(2.8.16等一般不超過16);

輸出格式:轉化成要求進製的格式輸出;

完整**:

#include

#include

void

change(char

*s,int

n,int

base)

;

intlen;

if(n==

0)

return;

change(s,n/base,base);
len=strlen(s);
s[len]=rule[n%base];
s[len+

1]='\0';

return;

}
int

main()

;
std::cin>>number>>base;
change(s,number,base);
std::cout

<

0;

}

分析:1、了解進製的同學都知道,所謂的幾進製就是滿幾進1,比如2進製就是滿2進1,10進製就是滿10進1 以此類推即可。

2、有了前期知識,我們可以來思考一下,如果不程式設計,我們如何求乙個十進位制數的x進製?

例如 我們有乙個十進位制數25,求它的x = 2進製;

可以用短除法:25/2 =12.....1    

12/2 = 6......0

6/2 = 3........0

3/2 = 1........1

1/2 = 0........1

所以:十進位制(25) =   二進位制(11001);

當x取其他值的時候把上面的2換成對應的值就好,方法都是一樣的;

4、接下來我們來考慮如何用**實現它:

考慮輸入:需要申請兩個變數,存放輸入需要的轉換的數字int n,存放轉化後的進製數int base

考慮輸出:我們最後輸出的轉化後的base進製格式,如果為二進位制的話,可能會出現8,9位的現象,所以顯然不能定義為int型變數,我們在這裡可以定義乙個字元型的陣列char s[80],因為不知道會有多少位輸出,所以先定義成80,(如果定義的過少的話有可能後面的值存不進來。當然你也可以定義成100,甚至1000 as you like 只多不少就行,當然還是要適當考慮記憶體空間多出來的部分會被浪費掉);陣列定義之後肯定要進行下標訪問,所以還需要定義乙個變數int len,表示陣列下標;

考慮結果:我們在上一步考慮結果的時候定義了乙個存放結果的陣列s,那我們到底應該把什麼存進去?顯而易見 求餘計算後的餘數,可是如果直接s[len] = n % base, 萬一我們的base > 10,那豈不是會放進去乙個大於十的數字給字元陣列,顯然不合適,我們都知道在進製表示的時候大於9之後用的是abcdef表示之後的數字,所以這部分就不能直接寫s[len] = n % base,不知道大家有沒有發現這樣乙個規律求餘的結果剛好對應了乙個從零開始的陣列下標,再加上之前我們做日期題得到的啟發 我們就可以在這裡定義乙個存放結果的陣列(因為我們存結果的是char 所以為了方便起見,這裡這個結果表我們也定義成char)char

rule=;

所以我們就有s[len] =rule[n % base];這裡還有個問題就是len的取值?比如我們之前已經存進去乙個,結果陣列長度為1,結果了所以這次應該存到第二個位置也就是s[1],可以這樣寫len = strlen(s);

接下來寫遞迴:既然知道了可以用遞迴的思想做,那就可以先思考一下遞迴所需要東西:

出口(結束條件):當數字除以進製基數商為0的時候就證明已經計算完成了 ,所以出口就可以表示為:

if (n % base == 0) return;

遞迴呼叫:change( ?, ?, ? )要傳什麼引數進去?首先因為每一次都要用到結果賦值操作,所以要把s陣列傳進去;接下來縮小問題規模,比如上一次我們算的是25/2,那再呼叫的時候就應該縮小一步所以就應該是把25/2 = 12傳進去;然後還需要乙個base表示轉換的進製基數;所以我們就可以這樣表示change(s,n/base,base)

現在基本上上已經準備好啦, 我們可以開始寫啦:

#include

#include // because we need strlen();

void change(char *s, int n, int base)

;

int len;

if (n % base == 0) return;

len = strlen(s);

s[len] =rule[n % base];

s[len +1] = ' \0 '

; // becaue when s =' \0 '

string char is over;

return ;

}

int main()

;

std::cin >> n >> base;

change(s, n, base);

std::cout << s << std::endl;

return 0;

}

好啦 這個問題就這樣解決啦 4不4很簡單 哈哈

希望這樣的思考過程能幫助到一些人

因為這個**只能實現10到其他的轉換,並沒有真正意義上實現進製之間的任意轉化,所以過一段時間博主計畫推出乙個可以任意轉換的**,用棧實現的思想過程,祈禱這段時間博主好好學習,早日學會棧 哈哈。

利用遞迴解決迷宮問題

利用遞迴解決迷宮問題 author rocco l public class migong for int i 0 i 8 i map 3 1 1 map 3 2 1 遍歷輸出地圖 for int i 0 i 8 i system.out.println 使用遞迴回溯給小球找路 setway map...

遞迴轉換進製

輸入乙個十進位制數n,將它轉換成r進製數輸出。輸入資料報含多個測試例項,每個測試例項包含兩個整數n 32位整數 和r 2 r 16,r 10 為每個測試例項輸出轉換後的數,每個輸出佔一行。如果r大於10,則對應的數字規則參考16進製制 比如,10用a表示,等等 7 2 23 12 4 3111 1b...

利用遞迴解決全排列問題

基本思想 以四個數為例,先把第乙個位置的數固定,遞迴地求後三個數的全排列,在求後三位的全排列時,把這三位中的第一位 整個數列中的第二位 固定,以此類推。當只剩最後乙個數要被固定時就可以輸出了。比如0123,先是輸出0123 全固定 然後2取消固定,和3進行交換,交換後一組全排列輸出完畢要交換回來。0...