/** 阿克曼(Ackmann)函數 【題目描述】 阿克曼(Ackmann)函數A(m,n)中,m,n定義域是非負整數(m<=3,n<=10),函數值定義爲: akm(m,n) = n+1; (m=0時) akm(m,n) = akm(m-1,1); (m>0,n=0時) akm(m,n) = akm(m-1,akm(m, n-1)); (m,n>0時) 【輸入】輸入m和n。 【輸出】函數值。 【輸入樣例】2 3 【輸出樣例】9 */
寫出遞歸與非遞歸算法,並輸出調用過程。java
import java.util.Stack; public class Main2 { public static void main( String[] args ) { System.out.println(AkmRecur(2, 3)); System.out.println(AkmNonRecur(2, 3)); } //遞歸 public static int AkmRecur(int m, int n) { if (m == 0) return n + 1; else if (n == 0) return AkmRecur(m - 1, 1); else return AkmRecur(m - 1, AkmRecur(m, n - 1)); } //非遞歸 public static int AkmNonRecur(int m, int n) { Stack<Integer> sx = new Stack<Integer>(); Stack<Integer> sy = new Stack<Integer>(); int x = 0; int y = 0; sx.push(m); sy.push(n); while ((!sx.empty()) && (!sy.empty())) { if (sx.peek() != 0 && sy.peek() == 0) {// m!=0 n==0 x = sx.peek(); y = sy.peek(); sx.pop(); sy.pop(); sx.push(x-1); sy.push(1); }else if (sx.peek() != 0 && sy.peek() != 0) {// m!=0 n!=0 while (sx.peek()!= 0 &&sy.peek()!= 0) { x = sx.peek(); y = sy.peek()-1; sx.pop(); sy.pop(); sx.push(x-1); sy.push(-1);//若是m!=0&&n!=0, n暫時存放-1,表明是一個總體 sx.push(x); sy.push(y); } } else {// m==0 y = sy.peek(); sx.pop(); if (sx.empty()){ return y + 1; } else { sy.pop();//彈出 y sy.pop();//彈出-1 sy.push(y+1); } } } return -1; } }