一步一步寫演算法(之爬樓梯)
阿新 • • 發佈:2019-02-03
【 宣告:版權所有,歡迎轉載,請勿用於商業用途。 聯絡信箱:feixiaoxing @163.com】
前兩天上網的時候看到一個特別有意思的題目,在這裡和朋友們分享一下:
有一個人準備開始爬樓梯,假設樓梯有n個,這個人只允許一次爬一個樓梯或者一次爬兩個樓梯,請問有多少種爬法?
在揭曉答案之前,朋友們可以自己先考慮一下:
這個人爬n層樓梯,那麼它也不是一下子就可以爬這麼高的,他只有兩個選擇,要麼從n-2層爬過來,要麼從n-1層爬過來。除此之外,他沒有別的選擇。此時相信朋友其實已經早看出來了,這就是一道基本的遞迴題目。
(1)首先我們建立一個函式,判斷函式的合法性
void jump_ladder(int layer, int* stack, int* top)
{
if(layer <= 0)
return;
return;
}
(2)判斷當前的層數是為1或者是否為2
(3)對於2中提及的列印函式進行設計,程式碼補全void jump_ladder(int layer, int* stack, int* top) { if(layer <= 0) return; if(layer == 1){ printf_layer_one(layer, stack, top); return; } if(layer == 2){ printf_layer_two(layer, stack, top); return; } return; }
注: a)程式碼中我們使用了巨集,注意這是一個do{}while(0)的結構,同時我們對x進行了字串強轉#define GENERAL_PRINT_MESSAGE(x)\ do {\ printf(#x);\ for(index = (*top) - 1 ; index >= 0; index --)\ printf("%d", stack[index]);\ printf("\n");\ }while(0) void printf_layer_one(int layer, int* stack, int* top) { int index ; GENERAL_PRINT_MESSAGE(1); } void printf_layer_two(int layer, int* stack, int* top) { int index; GENERAL_PRINT_MESSAGE(11); GENERAL_PRINT_MESSAGE(2); }
b)當剩下臺階為2的時候,此時有兩種情形,要麼一次跳完;要麼分兩次
(4)當階梯不為1或者2的時候,此時需要遞迴處理
void _jump_ladder(int layer, int* stack, int* top, int decrease)
{
stack[(*top)++] = decrease;
jump_ladder(layer, stack, top);
stack[--(*top)] = 0;
}
void jump_ladder(int layer, int* stack, int* top)
{
if(layer <= 0)
return;
if(layer == 1){
printf_layer_one(layer, stack, top);
return;
}
if(layer == 2){
printf_layer_two(layer, stack, top);
return;
}
_jump_ladder(layer- 1, stack, top, 1);
_jump_ladder(layer- 2, stack, top, 2);
}
祝:這裡在函式的結尾添加了一個函式,主要是遞迴的時候需要向堆疊中儲存一些資料,為了程式碼簡練,我們重新定義了一個函式。
總結:
1)這道題目和斐波那契數列十分類似,是一道地地道道的遞迴題目
2)遞迴的函式也需要好好測試,使用不當,極容易堆疊溢位或者死迴圈。對此,我們可以按照引數從小到大的順序依次測試,比如說,可以測試樓梯為1、2、3的時候應該怎麼執行,同時手算和程式相結合,不斷修正程式碼,完善程式碼。