写了一两天的样子,还是太菜了。
Ackerman函数规则:
Ack(m,n)=n+1(m==0时);Ack(m-1,1)(n==0且m!=0时);Ack(m-1,Ack(m,n-1))其他情况;
在网上查到的实现方法似乎有的在用goto label之类的语法,看起来有点乱,所以没有采用这样的方法。自己写了一个栈的结构体以及pop、push函数等,初学者看着应该会比较舒服一点。
就是说用了个chec_pos的变量来记录嵌套运算的点,不知道算不算取巧🤔。
#include<stdio.h>
int Ack(int m,int n){
int ans;
if(m==0){
printf("Arc(%d,%d)=%d\n",m,n,n+1);
return n+1;
}
if(n==0){
ans = Ack(m-1,1);
printf("Arc(%d,%d)=%d\n",m,n,ans);
return ans;
}
ans = Ack(m-1,Ack(m,n-1));
printf("Arc(%d,%d)=%d\n",m,n,ans);
return ans;
}
typedef struct stack{
int m,n,val,chec_pos;
stack* tail;
stack* next;
}Stack,*VEC;
void Build(VEC &head){
head=new stack;
head->next=new stack;head->next->chec_pos=0;
head->tail=head->next;
}
int isempty(VEC head){
return (head->next==head->tail);
}
void new_stack(VEC &head,int m,int n,int val){
VEC New=new stack;New->m=m;New->n=n;New->val=val;
New->next=head->next;
head->next=New;
}
void push(VEC &head,int m,int n,int chec_pos){
VEC New=new stack;New->m=m;New->n=n;New->chec_pos=chec_pos;
New->next=head->next;
head->next=New;
}
void pop(VEC &head){
VEC linshi;linshi=head;
head->next->tail=head->tail;
head=head->next;
delete linshi;
}
void inline show(VEC Head){
printf("\nAck(%d,%d) for %d\n",Head->next->m,Head->next->n,Head->next->chec_pos);
return;
}
void Ack_(int m,int n,VEC &Head){
int ans=0;
push(Head,m,n,0);
while(1){
if(Head->next->m==0){
ans=Head->next->n+1;
while(Head->next->chec_pos==0){
if(isempty(Head))break;
printf("Ack(%d,%d):\t%d\n",Head->next->m,Head->next->n,ans);
pop(Head);
}
if(isempty(Head))break;
if(Head->next->chec_pos==1){
printf("Ack(%d,%d):\t%d\n",Head->next->m,Head->next->n,ans);
Head->next->n=ans,Head->next->m-=1,Head->next->chec_pos=0;
}
continue;
}
if(Head->next->n==0){
push(Head,Head->next->m-1,1,0);
continue;
}
push(Head,Head->next->m,Head->next->n-1,1);
}
}
int main(){
Ack(2,1);
VEC Head;
Build(Head);
Ack_(2,1,Head);
return 0;}