Akm函式遞迴與非遞迴解法

2021-08-14 15:28:12 字數 2933 閱讀 2358

如下是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....