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

  • 0
  • 阿克曼函数的形式
  • 分析
  • 如何写代码
  • 解决办法
  • 代码
  • 1

0

这个星期,数据结构与算法的陈老师布置了一道题目,要求用非递归的算法计算阿克曼函数。在百度上找了很多个网址,都没有找到我想要的答案。于是,在我做出来之后,打算与大家分享一下我自己的想法。不足之处,请多多指教!

阿克曼函数的形式

如下图是我从《数据结构与程序设计》翻译版描述的阿克曼函数。
看到阿克曼函数的这个形式,毫无疑问第一个想到的肯定是用递归的算法。但是如果不用递归的算法,事情就变得麻烦起来了。

分析

说到用其它的算法代替递归算法,大部分第一个想到的肯定是使用循环,我第一个想到的也是循环,这是正确的。但是这个问题比较特殊,特殊之处就在于它的问题的出现是线性的。也就是说,你想要解决上一个问题,你只需要解决这一个问题;你想要解决这一个问题,你只需要解决下一个问题。注意我这里的用词:只需要!!!递归的实现其实就是一个堆栈出栈的过程。

下面就以计算A(2,1)的例子分析。如下图。

(注:这个图上的元素应该从下往上看,像堆栈一样)
如图,我们要解决A(2,1),就得解决A(1,A(2,0));要解决A(1,A(2,0)),就得解决A(2,0)… 以此类推,直到我们得到一个m=0的元素A(0,1),A(0,1)解决了之后,它的结果可以一直回到原来要解决的问题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)的结果为止,最终的结果是5。

如何写代码

从上面的分析,我们可以发现:
(1)每一个需要计算的元素是一个个向上地堆栈,直到遇到m=0的情况,此时A(0,n)可以计算出一个整数,之后就是出栈的操作。
(2)A(m,A(m1,m2)),这种情况在栈中是比较特殊的情况,当这里的m=0时,栈就能继续出栈了;但是m≠0的时候,我们还得继续向上堆栈。

解决办法

(1)声明两个栈s1、s2。
   s1存储m
   s2存储n
(2)遇到A(m,A(m1,m2))这种情况的时候,将n存储为-1,这是为了后面出栈的算法能够识别特殊情况,并且做出相应的处理。
(3)声明m和n,用于动态存储并操作m值和n值,这是因为在(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

这是我第一次写博客,有很多不足之处。代码是赶出来的,所以会有很多地方使用不当,请大家帮我指出错误!

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

  1. Ackerman函数 非递归 java_Ackerman(nm)函数的非递归算法.doc

    Ackerman(nm)函数的非递归算法 题目:已知Ackerman函数的定义如下: A(1,0)=2n=1,m=0 Ackerman= A(0,m)=1 n=0,m>=0 A(n,0)=n+2 ...

  2. 栈的应用4——递归函数的非递归形式(主讲阿克曼函数的非递归形式)

    递归 函数自己调用自己 如求阶乘函数: int jiecheng(int n) {if(n==0)return 1;if(n==1)return 1;else return n*jiecheng(n- ...

  3. 关于汉诺塔非递归算法的一点思考

    前段时间做编译课设时老师提到了汉诺塔的非递归不容易做出来,于是我趁着寒假有点时间就想试着搞一搞.下面我把我的一些草稿先列出来,以免以后忘记. 下面这个模型是适合于偶数个盘片的情况的.奇数的情况类似可得 ...

  4. ackman函数递归实现python_一个求ackerman函数的非递归算法

    ackerman函数的定义如下: n+1         m=0: ackerman(m,n)=        ackerman(m-1,1)     n=0,m>0: ackerman(m-1 ...

  5. Ackerman函数(递归与非递归算法实现)

    Ackerman函数 阿克曼函数是非原始递归函数的例子:它需要两个自然数作为输入值,输出一个自然数.它的输出值增长速度非常高. 计算Ackerman(m,n)函数递归算法与非递归算法(利用顺序栈) i ...

  6. 用python函数写斐波那契数列非递归,python 入门之斐波那契数列递归表达式算法和非递归算法...

    题目: 斐波那契数列是一组有规律的数列:1,1,2,3,5,8,13,........,那么我们怎么用python 来完成此算法,并求出第200位的值是多少 1.python 递归表达式实现: def ...

  7. 斐波那契数与二分法的递归与非递归算法及其复杂度分析

    1. 什么是斐波那契数? 这里我借用百度百科上的解释:斐波那契数,亦称之为斐波那契数列(意大利语: Successione di Fibonacci),又称黄金分割数列.费波那西数列.费波拿契数.费氏 ...

  8. 【数据结构】快速排序非递归算法及其改进

    在学数据结构中排序这一章节的时候,有一道有关快速排序的作业题描述如下: 按下述要求编写快速排序的非递归算法: 定义一个栈(或队列),把整个序列的上.下界入栈(或队列).当栈(或队列)非空时进行如下操作 ...

  9. (※)中序遍历二叉树的非递归算法

    在此之前,我们已经学习了中序遍历二叉树的递归算法,相信大家已经将其牢牢掌握了. 除了使用递归思想作为求解问题的钥匙,还可以借助栈来以非递归方式实现该问题的求解. 首先,我们要讨论存储二叉树结点信息的栈 ...

  10. 递归算法与非递归算法比较

    转载自:https://blog.csdn.net/mhsszm/article/details/78445591 非递归效率高:递归代码写出来思路清晰,可读性强. 生成可执行文件大小应该和编译器有关 ...

最新文章

  1. Android性能优化篇 [ 谷歌官方 ]
  2. 二叉树的层序遍历—leetcode102
  3. hihocoder-Week243-hiho字符串
  4. Dart编译技术在服务端的探索和应用
  5. Activiti 基础概念
  6. 让你瘦不停的23个小细节 - 生活至上,美容至尚!
  7. DataGridView
  8. hive与mysql的数据分区的异同
  9. 5. Browser 对象 - Screen 对象
  10. JupyterHub与OpenLDAP集成
  11. Ascii完整码表(256个)
  12. 修复 Mac 上“未找到 AirPrint 打印机”的错误
  13. logo计算机语言,LOGO语言
  14. Scrum 敏捷开发 笔记
  15. 关于电路中输入阻抗和输出阻抗大小的讨论
  16. vue—递归组件(vue组件name的作用之一)
  17. fastcgi php 进程用户 lighttpd,说说lighttpd的fastcgi
  18. VR眼镜转接线Type-c To DP加快充(乐得瑞LDr6282)
  19. 微信账单怎么查?微信流水账单怎么打印
  20. 基于Nginx实现访问控制,连接限制离

热门文章

  1. 【完美解决】ds1302外置时钟模块重复初始化时间问题(单片机掉电,模块电池供电)
  2. Word文件怎么快速查找关键词
  3. c语言求45678所有非平凡因子,近世代数基础习题课答案到第二章9题
  4. python排序算法——冒泡排序时间复杂度
  5. 专业pdf转word转换软件 pdf转换器 pdf转txt pdf转ppt、excel
  6. GB / ISO / 等保 网络安全相关标准法规
  7. java坦克大战 素材_坦克大战 游戏源码+ 素材+文档(了解面向对象的具体编程)
  8. iptv原版固件_永久免费看IPTV,有了这固件可看高清流畅稳定直播
  9. vivado使用入门
  10. UWP,WPF 打包Roboto 字体