`
terrynoya
  • 浏览: 5686 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

ArrayList实现Ackerman非递归算法

阅读更多
Ackerman(m,n)函数的递归定义为
public static int ackerman(int a,int b){
   if(a==0)
      return b+1;
   else if(a!=0&&b==0)
      return ackerman(a-1,1);
   else
      return ackerman(a-1,ackerman(a,b-1));
}

递归转换为非递归需要使用栈来模拟递归
那么就选用ArrayList充当下栈吧,对我来说用起来比较熟悉,你可以使用java自己的Stack类

栈结构为
m n result

把它写成一个bean作为我们的栈的一个小块
class Stack{
	private int m;
	private int n;
	private int result;
	
	public Stack(int m,int n,int result){
		this.m=m;
		this.n=n;
		this.result=result;
	}
	get/set()方法省略	
}


n或result=-1时代表解暂时未得到

下面是实现算法的主要思想
while(栈非空&&没有得到答案){
    取栈顶对象stacktemp
    if(该元素.result还没有解){
        if(m和n都!=0){
           //因为Ackerman在这个情况下会分解成2个函数,所以都要进栈
             new stack1(m-1,-1,-1)进栈
             new stack2(m,n-1,-1)进栈
             ArrayList.add(stack1和stack2);
        }
        else if(n==0){
           //这个情况下只分解为一个函数
             new stack(m-1,1,-1)进栈
        }
        else if(m==0){
            //这个情况可以得到stacktemp的结果,即n+1;
            修改stacktemp的result
         }
    }
    //如果的到的stacktemp是有解的进行出栈动作
    else{
       if(栈的长度==1){
          //说明得到我们的结果了
            得到结果
            设置一个flag让循环可以终止
       }
       if(stacktemp.m为0){
           将stacktemp.result传给上一个栈的result
           stacktemp出栈
       }
       else if(stacktemp.m!=0){
           if(如果上一个栈的n==-1){
                该元素的结果传给上一个栈的n
                stacktemp出栈
            }
            else{
                 //这是关键点,因为Ackerman函数是双递归,需要递归2次,这个else恰好是2个分支的交汇处
                 将stacktemp.result传给上一个栈的result
                 stacktemp出栈
            }
       }
    }
}

完整代码如下
package com.datastructure;

import java.util.ArrayList;
import java.util.Calendar;

public class AckermanWithoutCycle {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO 自动生成方法存根
		int result=-1;
		boolean gotAnswer=false;
		long starttime=-1;
		long endtime=-1;
//		System.out.println("请输入Ackerman的2个参数");
//		Scanner sc=new Scanner(System.in);
//		int a=sc.nextInt();
//		int b=sc.nextInt();
		int a=4;
		int b=1;
		ArrayList<Stack> stacklist=new ArrayList<Stack>();
		Stack stack=new Stack(a,b,-1);
		stacklist.add(stack);
		starttime=Calendar.getInstance().getTimeInMillis();
		while(stacklist.size()>0&&!gotAnswer){
			//取栈顶元素
			Stack stacktemp=stacklist.get(stacklist.size()-1);
			//如果该元素还没有解
			if(stacktemp.getResult()==-1){	
				if(stacktemp.getM()!=0&&stacktemp.getN()!=0){
					Stack stack1=new Stack(stacktemp.getM()-1,-1,-1);
					Stack stack2=new Stack(stacktemp.getM(),stacktemp.getN()-1,-1);
					stacklist.add(stack1);
					stacklist.add(stack2);
				}
				else if(stacktemp.getN()==0){
					Stack stack1=new Stack(stacktemp.getM()-1,1,-1);
					stacklist.add(stack1);
				}
				//如果m==0那么该栈的解是n+1
				else if(stacktemp.getM()==0&&stacktemp.getN()!=-1){
					stacktemp.setResult(stacktemp.getN()+1);
				}
			}
			//如果该元素有解
			else{
				if(stacklist.size()==1){
					result=stacktemp.getResult();
					gotAnswer=true;
					endtime=Calendar.getInstance().getTimeInMillis();
					break;
				}
				//如果m为0
				if(stacktemp.getM()==0){
					//讲该元素的结果传给上一个栈的result
					stacklist.get(stacklist.size()-2).setResult(stacktemp.getResult());
					stacklist.remove(stacktemp);
				}
				//如果不为0
				else if(stacktemp.getM()!=0){
					//如果上一个栈的n==-1,该元素的结果传给上一个栈的n
					if(stacklist.get(stacklist.size()-2).getN()==-1){
						stacklist.get(stacklist.size()-2).setN(stacktemp.getResult());
						stacklist.remove(stacktemp);
					}
					else{
						stacklist.get(stacklist.size()-2).setResult(stacktemp.getResult());
						stacklist.remove(stacktemp);
					}
				}
			}
		}
		System.out.println("结果为:"+result+"耗时"+(endtime-starttime)+"ms");
	}
}
class Stack{
	private int m;
	private int n;
	private int result;
	
	public Stack(int m,int n,int result){
		this.m=m;
		this.n=n;
		this.result=result;
	}
	public int getM() {
		return m;
	}
	public void setM(int m) {
		this.m = m;
	}
	public int getN() {
		return n;
	}
	public void setN(int n) {
		this.n = n;
	}
	public int getResult() {
		return result;
	}
	public void setResult(int result) {
		this.result = result;
	}
	
}
分享到:
评论

相关推荐

    大数的阶乘非递归算法C#源码

    在这个主题中,我们将深入探讨如何用非递归算法来实现大数阶乘计算,并且利用ArrayList来存储中间结果。 首先,让我们了解阶乘的概念。阶乘是数学中的一个运算,对于非负整数n,其阶乘表示为所有小于等于n的正整数...

    java编写的递归算法的经典事例

    本文将详细介绍一个用Java编写的递归算法实例,该实例用于实现字符数组的所有可能全排列。通过这个例子,我们可以深入理解递归的基本概念、工作原理以及如何在实际编程中应用递归来解决问题。 #### 代码解析 #####...

    Java ArrayList实现的快排,归并排序,堆排序

    本篇将重点讲解如何利用ArrayList实现快速排序(Quick Sort)、归并排序(Merge Sort)和堆排序(Heap Sort)这三种经典的排序算法,并探讨它们的原理、优缺点以及在实际应用中的选择。 **快速排序(Quick Sort)**...

    ArrayList实现对产品CRUD

    在Java编程语言中,ArrayList是Java集合框架的重要组成部分,它属于List接口的一个具体实现,用于存储可变大小的有序对象列表。在这个“ArrayList实现对产品CRUD”的项目中,我们将探讨如何利用面向对象编程(OOP)...

    浅析ArrayList内部实现

    浅析ArrayList内部实现 ArrayList是Java集合框架中的一种常用数据结构,能够存储任意多个对象,并且可以自由扩展,弥补了数组的定长的缺陷。下面我们将深入探讨ArrayList的内部实现机理。 ArrayList的内部实现机理...

    ArrayList的实现原理

    ArrayList是Java集合框架中常用的动态数组,它是List接口的一个实现,允许存储包括null在内的所有元素。ArrayList的主要特点是通过数组来存储元素,提供了丰富的操作方法,包括添加、删除、修改和查询等。下面是...

    android arraylist 实现 listview

    在这个场景中,我们将探讨如何利用ArrayList来实现ListView,以及如何添加编辑、新增、删除功能,以及在Activity间传递参数,同时还会涉及到ContextMenu和OptionsMenu的实现,以及长按事件的处理。 首先,我们需要...

    模拟arraylist底层实现

    模拟ArrayList底层实现 在Java中,ArrayList是一种常用的集合类,提供了许多实用的方法来操作集合数据,而本文则尝试模拟ArrayList的底层实现,通过自定义集合实现类MyArrayList,来实现基本的集合操作。 模拟...

    Java使用递归算法求交错幂集(源代码)

    ### Java使用递归算法求交错幂集(源代码) ...通过递归算法,我们成功实现了交错幂集的概念,并通过Java语言进行了具体实现。这种方法不仅能够清晰地展示递归的思想,而且也适用于解决实际问题中类似的组合问题。

    用java自己实现的arrayList

    用java自己实现的arrayList,比较详细,有助于初学者理解arrayList的基本概念和基础用法

    Java学生成绩管理系统实例(ArrayList)

    实现一个学生成绩管理的简单系统。要求可以添加、删除、修改、查询成绩 创建界面相关的接口:将菜单中显示的内容定义成若干字符串常量,放入一个接口Menu中以便使用 TestDemo(主类) import java.util.ArrayList; ...

    FP树增长算法的java实现

    使用Java的集合框架,如ArrayList和HashMap,可以方便地实现这些数据结构和操作。 在提供的`fpgrowth`文件中,可能包含了FP树算法的具体Java实现代码,包括类定义、方法实现以及可能的数据示例。通过阅读和理解这段...

    我的ArrayList实现

    但是,迭代过程中修改ArrayList(非迭代器自身调用的remove方法)可能不会抛出异常,而是造成未定义的行为,因此在并发编程中需要格外注意。 了解ArrayList的内部机制对于优化代码性能至关重要。例如,预估...

    深入Java集合学习系列(三):ArrayList实现原理

    Java集合框架中,ArrayList是一种常见的集合实现类,用于存储和操作对象集合。ArrayList基于动态数组的数据结构,因此它能够提供自动扩容的功能,同时也能够快速地进行随机访问。本篇文档将深入探讨ArrayList的内部...

    用java实现的栈,通过使用ArrayList的方法

    此方法是通过java提供的ArrayList方法对栈的实现;

    ArrayList的一个C++类模板实现

    不过,根据标题和描述,这里我们讨论的是一个用C++实现的ArrayList类模板,它采用了双层散列技术来提高性能。这个实现旨在提供高效的数据存储和操作,特别是在处理大量数据时。 首先,让我们深入了解ArrayList的...

    用ArrayList实现用户信息的添加,删除,更新,查询

    在Java编程中,ArrayList是一个常用的集合类,它继承自AbstractList并实现了List接口。ArrayList以动态数组的形式存储数据,提供了一种高效的方式来管理和操作对象序列。在这个场景中,我们使用ArrayList来实现用户...

    C#用递归算法实现:一列数的规则如下: 1、1、2、3、5、8、13、21、34,求第30位数是多少

    **非递归算法实现** 方法二采用了非递归策略,使用ArrayList存储序列中的数字。首先,构造函数`Class1(int num)`初始化ArrayList并填充前`num`个斐波那契数。`Calculation`方法用于根据已存储的数字计算新的...

Global site tag (gtag.js) - Google Analytics