如下是akm函式的遞迴演算法,根據akm函式的遞迴定義就可以得出,請參考:
int akmrecur(int m, int n)
非遞迴演算法沒有遞迴演算法簡單,你先計算一下akm(2,1),多計算幾遍(我建議2遍,並在計算的過程中,分析一下計算過程有什麼規律)。
如果你計算完了,就可以看下面的分析了(請不要懶,應為計算的量是比較小的)
①計算的過程中,我們發現有這樣的變化
akm(2,1)=akm[1,akm(2,0)](你可能注意到這是第一步)
然後如果要繼續算下去,那麼我們要計算出
akm(2,0)
這個akm函式的值。所以第一步思考,如何讓計算機懂得計算akm[1,akm(2,0)]裡面的akm(2,0)而不是看到akm[1,akm(2,0)]就傻掉了(死板的計算機如果只懂的計算akm(2,0)這種形式的話)。如果仔細觀察一下,你會發現右邊的akm函式多了乙個數字0,或者說數字多了乙個(左邊只有2和0兩個數字,右邊有1,2和0三個數字),所以可以通過這個特點設定乙個tag標誌,-1表示左邊的形式,如果非-1的話,那麼就是右邊的形式,計算機可以通過觀察tag來區別計算左邊還是右邊(如果你覺得不太懂,可以等下看演算法,演算法很清晰,比我這裡囉嗦要好)
②如果計算得到了值(akm中,當m=0的時候,函式的值確定了,為n+1),如何返回?如果你計算了,請觀察一下過程,發現你要帶回的地方,恰好是形式轉變的地方(形如akm(2,0)=akm[1,akm(2,0)]的地方),所以通過這個特點,可以賦值在右邊式子的第二個數(把帶回的值賦值給右邊式子的第二個數,你不也是這樣帶回的嗎?),而要一直略過的地方(就是得到的值要帶回,離恰好形式轉變的式子中間應該有不少等式),可以發現都是akm(x,y)的形式,而且其tag值應為-1(如果你覺得聽得很模糊,沒關係,等下看下演算法就全懂了)
③還有一點,就是如何帶回結果的問題,我不善於表達,請直達下面的**吧。
**如下:
int akmnrecur(int m, int n)
if (v.m == 0)//複雜度最高的情況
while (x.k == -1);
pop(&s);
x.k = -1;
x.n = value;
push(&s, x);//這裡表示計算機完成對akm[1,akm(2,0)]形式中akm(2,0)的計算了,現在應該是akm(1,3)這種形式
} else if (v.n == 0)//如果是這種情況,那麼需要入棧,應為還不知道結果,要繼續運算
else//這種情況同v.n==0分析
}}
緊湊版:
int akmnrecur(int m, int n)
if (v.m == 0)
while (x.k == -1);
pop(&s);
x.k = -1, x.n = value;
} else if (v.n == 0)//如果是這種情況,那麼需要入棧,應為還不知道結果,要繼續運算
else//這種情況同v.n==0分析
push(&s, x);
}}
請相信這個**,儘管他執行不了太大的akm(這真不能怪演算法,akm函式的值增長速度太快了,只是微不足道地提公升一下數值,計算機都會喘不過氣來),幾乎是一遍ac的(為什麼幾乎呢?中間除錯了時候x.k=-1寫出x.k==-1...比較難發現喲)
如果你要執行,你得需要整個源**,如下:
#include "stdafx.h"
#include#include#define stack_ini_size 10
#define stack_inc_size 2
#define status int
#define overflow -1
#define error 0
#define ok 1
typedef struct akmstack
akmelem;
typedef struct seqstack
seqstack;
status initstack(seqstack *s);
status extern(seqstack *s);
status push(seqstack *s, akmelem x);
status pop(seqstack *s);
status gettop(seqstack *s, akmelem *e);
bool isempty(seqstack *s);
int akmrecur(int m, int n);
int akmnrecur(int m, int n);
int main()
int akmrecur(int m, int n)
int akmnrecur(int m, int n)
if (v.m == 0)
while (x.k == -1);
pop(&s);
x.k = -1;
x.n = value;
push(&s, x);
} else if (v.n == 0)//如果是這種情況,那麼需要入棧,應為還不知道結果,要繼續運算
else//這種情況同v.n==0分析
}}status initstack(seqstack *s)
;status extern(seqstack *s)
status push(seqstack *s, akmelem x)
status pop(seqstack *s)
status gettop(seqstack *s, akmelem *e)
bool isempty(seqstack *s)
我覺得呢,還是自己多計算幾個akm函式,計算的過程中,就會發現規律,總結規律,**就出來了。
希望對你有幫助。
N皇后問題(遞迴與非遞迴解法)
最近演算法老師講到了 皇后問題,我順便在這邊總結一下他的思路,主要還是深搜加剪枝 解題思路 用陣列 儲存每個皇后在下標行中的位置 即列 然後進行深搜加剪枝判斷,如果不符合條件了,則回朔 思路很簡單,下面的 包含兩種解法 include include define m 8 修改此處改變皇后的基數 b...
漢諾塔問題的遞迴解法與非遞迴解法(堆疊解法)
1.遞迴演算法,三步 移動n 1到b,移動1到c,移動n 1到c。includeusing namespace std int j 1 void move char a,char c void hanio int n,char a,char b,char c hanio n 1,a,c,b move...
N皇后問題的遞迴與非遞迴解法
n皇后問題 n皇后問題是將n個皇后放置在n n的棋盤上,皇后彼此之間不能相互攻擊。給定乙個整數n,返回所有不同的n皇后問題的解決方案。每個解決方案包含乙個明確的n皇后放置布局,其中 q 和 分別表示乙個女王和乙個空位置。樣例對於4皇后問題存在兩種解決的方案 q.solution 1 q q.q.q....