日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

关于阿克曼函数(akermann)非递归算法的一点见解 c++

發(fā)布時間:2023/12/14 c/c++ 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于阿克曼函数(akermann)非递归算法的一点见解 c++ 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

關(guān)于阿克曼函數(shù)(akermann)非遞歸算法的一點(diǎn)見解

  • 0
  • 阿克曼函數(shù)的形式
  • 分析
  • 如何寫代碼
  • 解決辦法
  • 代碼
  • 1

0

這個星期,數(shù)據(jù)結(jié)構(gòu)與算法的陳老師布置了一道題目,要求用非遞歸的算法計(jì)算阿克曼函數(shù)。在百度上找了很多個網(wǎng)址,都沒有找到我想要的答案。于是,在我做出來之后,打算與大家分享一下我自己的想法。不足之處,請多多指教!

阿克曼函數(shù)的形式

如下圖是我從《數(shù)據(jù)結(jié)構(gòu)與程序設(shè)計(jì)》翻譯版描述的阿克曼函數(shù)。
看到阿克曼函數(shù)的這個形式,毫無疑問第一個想到的肯定是用遞歸的算法。但是如果不用遞歸的算法,事情就變得麻煩起來了。

分析

說到用其它的算法代替遞歸算法,大部分第一個想到的肯定是使用循環(huán),我第一個想到的也是循環(huán),這是正確的。但是這個問題比較特殊,特殊之處就在于它的問題的出現(xiàn)是線性的。也就是說,你想要解決上一個問題,你只需要解決這一個問題;你想要解決這一個問題,你只需要解決下一個問題。注意我這里的用詞:只需要!!!遞歸的實(shí)現(xiàn)其實(shí)就是一個堆棧出棧的過程。

下面就以計(jì)算A(2,1)的例子分析。如下圖。

(注:這個圖上的元素應(yīng)該從下往上看,像堆棧一樣)
如圖,我們要解決A(2,1),就得解決A(1,A(2,0));要解決A(1,A(2,0)),就得解決A(2,0)… 以此類推,直到我們得到一個m=0的元素A(0,1),A(0,1)解決了之后,它的結(jié)果可以一直回到原來要解決的問題A(1,A(2,0)),也即是A(1,3)。往后同樣分析,要解決A(1,3),就得先解決A(0,A(1,2));要解決A(0,A(1,2)),就得先解決A(1,2)…直到我們最終推出A(2,1)的結(jié)果為止,最終的結(jié)果是5。

如何寫代碼

從上面的分析,我們可以發(fā)現(xiàn):
(1)每一個需要計(jì)算的元素是一個個向上地堆棧,直到遇到m=0的情況,此時A(0,n)可以計(jì)算出一個整數(shù),之后就是出棧的操作。
(2)A(m,A(m1,m2)),這種情況在棧中是比較特殊的情況,當(dāng)這里的m=0時,棧就能繼續(xù)出棧了;但是m≠0的時候,我們還得繼續(xù)向上堆棧。

解決辦法

(1)聲明兩個棧s1、s2。
   s1存儲m
   s2存儲n
(2)遇到A(m,A(m1,m2))這種情況的時候,將n存儲為-1,這是為了后面出棧的算法能夠識別特殊情況,并且做出相應(yīng)的處理。
(3)聲明m和n,用于動態(tài)存儲并操作m值和n值,這是因?yàn)樵?#xff08;2)的要求下,n可能在棧s2中存為-1,此時存儲的值是一個待定值。

代碼

#include<iostream> #include<stack> using namespace std; int asker(int m, int n) {stack<int> s1;stack<int> s2;s1.push(m);s2.push(n);while (!s1.empty()){while (m != 0){if (n == 0){m = m - 1;n = 1;s1.push(m);s2.push(n);}else{n = n - 1;s1.push(m - 1);s2.push(-1);}}n = n + 1;while ((!s1.empty())&& (s2.top() != -1)){s1.pop();s2.pop();}if(!s1.empty()){m = s1.top();s2.pop();s2.push(n);}}return n; } void main() {cout << asker(2, 1); }

1

這是我第一次寫博客,有很多不足之處。代碼是趕出來的,所以會有很多地方使用不當(dāng),請大家?guī)臀抑赋鲥e誤!

總結(jié)

以上是生活随笔為你收集整理的关于阿克曼函数(akermann)非递归算法的一点见解 c++的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。