如下是Akm函数的递归算法,根据Akm函数的递归定义就可以得出,请参考:

int AkmRecur(int m, int n)
{if (m == 0)return n + 1;else if (n == 0)return AkmRecur(m - 1, 1);elseAkmRecur(m - 1, AkmRecur(m, n - 1));
}

非递归算法没有递归算法简单,你先计算一下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)
{SeqStack S;InitStack(&S);AkmElem e;e.m = m, e.n = n, e.k = -1;//一开始的m,n压入栈中Push(&S, e);while (1){AkmElem v, x;GetTop(&S, &v);if (v.k != -1){v.m = v.n;v.n = v.k;//-1表示是akm(x,y)形式,如果不是这个形式,则k应该等于一个正整数}if (v.m == 0)//复杂度最高的情况{int value;value = v.n + 1;//计算结果do{Pop(&S);if (IsEmpty(&S))//如果连续出栈导致栈空,那么表示返回值就是akm函数的结果return value;elseGetTop(&S, &x);} 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)//如果是这种情况,那么需要入栈,应为还不知道结果,要继续运算{x.k = -1;x.m = v.m - 1;x.n = 1;Push(&S, x);}else//这种情况同v.n==0分析{x.m = v.m - 1;x.n = v.m;x.k = v.n - 1;Push(&S, x);}}
}

紧凑版:

int AkmNRecur(int m, int n)
{SeqStack S;InitStack(&S);AkmElem e, v, x;e.m = m, e.n = n, e.k = -1;//一开始的m,n压入栈中Push(&S, e);while (true){GetTop(&S, &v);if (v.k != -1){v.m = v.n, v.n = v.k;}if (v.m == 0){int value = v.n + 1;//计算结果do{Pop(&S);if (IsEmpty(&S))//如果连续出栈导致栈空,那么表示返回值就是akm函数的结果return value;GetTop(&S, &x);} while (x.k == -1);Pop(&S);x.k = -1, x.n = value;}else if (v.n == 0)//如果是这种情况,那么需要入栈,应为还不知道结果,要继续运算{x.k = -1, x.m = v.m - 1, x.n = 1;}else//这种情况同v.n==0分析{x.m = v.m - 1,x.n = v.m, x.k = v.n - 1;}Push(&S, x);}
}

请相信这个代码,尽管他运行不了太大的Akm(这真不能怪算法,Akm函数的值增长速度太快了,只是微不足道地提升一下数值,计算机都会喘不过气来),几乎是一遍AC的(为什么几乎呢?中间调试了时候x.k=-1写出x.k==-1...比较难发现哟)

如果你要运行,你得需要整个源代码,如下:

#include "stdafx.h"
#include<stdio.h>
#include<iostream>
#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
{int m;int n;int k;
}AkmElem;
typedef struct SeqStack
{AkmElem *base;int      top;int      size;
}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()
{using namespace std;cout << AkmRecur(3, 2) << endl;cout << AkmNRecur(3, 2) << endl;return 0;
}int AkmRecur(int m, int n)
{if (m == 0)return n + 1;else if (n == 0)return AkmRecur(m - 1, 1);elseAkmRecur(m - 1, AkmRecur(m, n - 1));
}int AkmNRecur(int m, int n)
{SeqStack S;InitStack(&S);AkmElem e;e.m = m, e.n = n, e.k = -1;//一开始的m,n压入栈中Push(&S, e);while (1){AkmElem v, x;GetTop(&S, &v);if (v.k != -1){v.m = v.n;v.n = v.k;}if (v.m == 0){int value;value = v.n + 1;//计算结果do{Pop(&S);if (IsEmpty(&S))//如果连续出栈导致栈空,那么表示返回值就是akm函数的结果return value;elseGetTop(&S, &x);} while (x.k == -1);Pop(&S);x.k = -1;x.n = value;Push(&S, x);}else if (v.n == 0)//如果是这种情况,那么需要入栈,应为还不知道结果,要继续运算{x.k = -1;x.m = v.m - 1;x.n = 1;Push(&S, x);}else//这种情况同v.n==0分析{x.m = v.m - 1;x.n = v.m;x.k = v.n - 1;Push(&S, x);}}
}Status InitStack(SeqStack *S)
{S->base = (AkmElem*)malloc(sizeof(AkmElem)*STACK_INI_SIZE);if (!S->base)return OVERFLOW;S->size = STACK_INI_SIZE;S->top = 0;return OK;
};Status Extern(SeqStack *S)
{AkmElem *newbase;newbase = (AkmElem*)realloc(S->base, (S->size + STACK_INC_SIZE) * sizeof(AkmElem));if (!newbase)return OVERFLOW;S->base = newbase;S->size += STACK_INC_SIZE;return OK;
}Status Push(SeqStack *S, AkmElem x)
{if (S->top == S->size && !Extern(S))return OVERFLOW;S->base[S->top++] = x;return OK;
}Status Pop(SeqStack *S)
{if (IsEmpty(S))return ERROR;S->top--;return OK;
}Status GetTop(SeqStack *S, AkmElem *e)
{if (IsEmpty(S))return ERROR;(*e) = S->base[S->top - 1];return OK;
}bool IsEmpty(SeqStack *S)
{return S->top == 0;
}

我觉得呢,还是自己多计算几个Akm函数,计算的过程中,就会发现规律,总结规律,代码就出来了。

希望对你有帮助。

Akm函数递归与非递归解法相关推荐

  1. 全排列(含递归和非递归的解法)

    全排列在近几年各大网络公司的笔试中出现的比较频繁 首先来看看题目是如何要求的(百度迅雷校招笔试题). 用C++写一个函数, 如 Foo(const char *str), 打印出 str 的全排列, ...

  2. 编写函数 int fac(int x)计算 x!的值。在主函数中输入 n 和 m 的值,通过调用函数 fac 计算m Cn 的值(要求分别用递归和非递归的方法编写函数 fac)

    编写函数 int fac(int x)计算 x!的值.在主函数中输入 n 和 m 的值,通过调用函数 fac 计算m Cn 的值(要求分别用递归和非递归的方法编写函数 fac) 递归: #includ ...

  3. c语言中fact函数怎么调用,C语言程序题: 1、编写一个求n!的函数fact(n),要求fact函数分别用递归和非递归两种方法实现...

    点击查看C语言程序题: 1.编写一个求n!的函数fact(n),要求fact函数分别用递归和非递归两种方法实现具体信息 答:int fac(int n) //非递归{int f=1; for(;n;) ...

  4. C++第七次作业(函数_递归与非递归_多文件)

    文章目录: 一:C++递归与非递归实现整数的阶乘 代码实现 运行结果 二:C++递归与非递归实现Fibonacci数列的计算:a0=1; a1=1; a2=a0+a1; a3=a1+a2; ..... ...

  5. 分别采用递归和非递归方式编写两个函数,求一棵二叉树中叶子节点个数

    分别采用递归和非递归方式编写两个函数,求一棵二叉树中叶子节点个数 #include #include #define MAXSIZE 50 typedef char datatype; typedef ...

  6. C和指针之函数之实现阶乘和斐波那契数(递归和非递归)

    1.问题 实现阶乘和斐波那契数(递归和非递归) 2.代码实现 #include <stdio.h>int num = 0; //递归实现斐波那契数 // n <=2, f(n) = ...

  7. java 反转二叉树 非递归_【刷算法】翻转二叉树的递归和非递归解法

    题目描述 操作给定的二叉树,将其变翻转为源二叉树的镜像. 输入描述: 1 1 / \ / \ 2 3 ------> 3 2 / \ / \ / \ / \ 4 5 6 7 7 6 5 4 解题 ...

  8. 数据结构:利用栈,将递归转换为非递归的方法

    利用栈将递归转换为非递归 对于一般的递归过程,仿照递归算法执行过程中递归工作栈的状态变化,可直接写出相应的非递归算法. 步骤 第一次调用的参数push进堆栈,原有递归代码外层加一个while循环,判断 ...

  9. C#实现(递归和非递归)快速排序和简单排序

    C#实现(递归和非递归)快速排序和简单排序 本人因为最近工作用到了一些排序算法,就把几个简单的排序算法,想冒泡排序,选择排序,插入排序,奇偶排序和快速排序等整理了出来,代码用C#代码实现,并且通过了测 ...

  10. 全排列(递归与非递归实现)

    全排列问题在公司笔试的时候非经常见,这里介绍其递归与非递归实现. 递归算法 1.算法简述 简单地说:就是第一个数分别以后面的数进行交换 E.g:E = (a , b , c),则 prem(E)= a ...

最新文章

  1. 编写同时在PyTorch和Tensorflow上工作的代码
  2. Spring AOP 本质(3)
  3. .NET Core 返回结果统一封装
  4. 树莓派摄像头 C++ OpenCV YoloV3 实现实时目标检测
  5. java获取cpu使用率_再一次生产 CPU 高负载排查实践
  6. python读取数据集前十行_Python读取数据集并消除数据中的空行方法
  7. feign整合sential_Sentinel 和 Feign 集成时,方法名称写错
  8. html css js网页制作实例,HTML+CSS+JavaScript网页制作案例教程
  9. Linux技术简历项目经验示例(二)
  10. python打开读取文件内容
  11. 模拟静态小米商城官网html+css
  12. 世界上都有哪些常用的聊天软件?
  13. Ecowalker充气足球门,为青少年足球训练保驾护航!
  14. pytorch学习随手记
  15. Android-VideoView启动页视频,8.0崩溃解决
  16. APPNP:PREDICT THEN PROPAGATE: GRAPH NEURAL NETWORKS MEET PERSONALIZED PAGERANK
  17. Cortana小娜失败背后,微软的傲慢与偏见
  18. 个人学习笔记——Python篇(基础)
  19. 都是我的错,错不该拒绝HR的心意
  20. 猿创征文|深入剖析多态的实现原理与虚函数指针

热门文章

  1. 1920x1080平板 android,高清是王道!1080P分辨率屏幕平板大搜罗
  2. 快手和抖音怎么打开微信小程序
  3. 微信小程序定位权限封装
  4. 统计字符串中字幕出现的数量(Map案例)
  5. 思齐什么意思_思齐的寓意
  6. 曾国藩戒烟——人但有恒,事物不成
  7. Echarts-实现3D柱状图显示,并单个柱子变色
  8. 静态内部类、静态变量的加载次数-理解静态内部类实现线程安全的单例模式
  9. Android之SQLite数据库及SQLiteStudio工具的使用
  10. Android控件隐藏方式