繁体   English   中英

使用java中的循环将递归方法转换为非递归方法

[英]Converting a recursive method into a non-recursive method using loop in java

因此,我正在制作一个游戏,其中指令是使用存储在标记索引处的整数(在这种情况下为圆形)在数组内向左或向右移动,直到我们可以将圆圈到达数组的最后一个索引。 数组的最后一个整数始终为0。

例如,

[4] 1 2 3 1 0,这里我们从圈0(索引)开始

我们向右移动4,4 1 2 3 [1] 0

然后1次向右,4 1 2 3 1 [0]。 在这里游戏停止,我们赢了。

对于递归方法,我的代码如下:

public static boolean rightWing (int circle, int[] game, List<Integer> checkerList){

int last = game.length-1;

if (circle == last){ // base case for recursion
    return true;
}

if (circle < 0){ // if we go out of bounds on the left
    return false;
}

if (circle > last){ // if we go out of bounds on the right
    return false;
}

if (checkerList.contains(circle)){ // check for the impossible case 
    return false;
}

checkerList.add(circle); // adds the circle value for the last check to checkerList so we can check for the impossible case

int moveRight = circle + game[circle]; // these two integers help the game move according to the value of the int at circle
int moveLeft = circle - game[circle];

return rightWing( moveRight, game, checkerList) || rightWing(moveLeft, game,checkerList);
}

这很好用,但唯一的问题是它的递归和缓慢。 我正在尝试使用循环和堆栈/队列重新设计它以使其更有效,但是在写完之后我陷入困境(伪):

   Boolean rightWing (int circle, List<int> game, List<int> checkerList)

Int lastPlace = game.size() - 1

For int i <- 0 to game.size() - 1 do

    If i equals lastPlace then // returns true when i is at the last position of the game
        Return true

关于如何前进的任何意见将不胜感激!

最重要的一点:当调试应用程序缓慢时,您应首先收集一些性能数据,以确定您的应用程序花费大部分时间的位置。 否则修复性能效率低下。 你可以使用与jdk捆绑在一起的jvisualvm

数据结构统治着绩效世界

它可以缓慢的原因之一是:

if (checkerList.contains(circle)){ // check for the impossible case 
    return false;
}

列表中的项目越多,它就越慢。 List具有contains方法的linear complexity 如果你使用HashSet你可以使它变得constant complexity 例如,如果你有100个元素的列表,这个部分将使用List比使用HashSet慢100倍。

可能需要一些时间的另一件事是装箱/拆箱:每次将元素放入列表时, int都被包装到新的Integer对象中 - 这称为装箱。 您可能希望使用IntSet来避免装箱/取消装箱并节省GC时间。

转换为迭代形式

我不希望这会影响您的应用程序速度,只是为了完整答案。

将递归应用程序转换为迭代形式非常简单:封面下的每个方法参数都会在您(或其他函数)的每次调用时存储在隐藏堆栈中。 在转换过程中,您只需创建自己的堆栈并手动管理它

public static boolean rightWingRecursive(int circle, int[] game) {
    Set<Integer> checkerList = new HashSet<Integer>();
    Deque<Integer> statesToExplore = new LinkedList<>();

    int last = game.length - 1;

    statesToExplore.push(circle);

    while (!statesToExplore.isEmpty()) {
        int circleState = statesToExplore.pop();

        if (circleState == last) { // base case for recursion
            return true;
        }

        if (circleState < 0) { // if we go out of bounds on the left
            continue;
        }

        if (circleState > last) { // if we go out of bounds on the right
            continue;
        }

        if (checkerList.contains(circle)) { // check for the impossible case
            continue;
        }

        checkerList.add(circle); // adds the circle value for the last check to
        // checkerList so we can check for the
        // impossible case
        int moveRight = circle + game[circle]; // these two integers help the
        // game move according to the
        // value of the int at circle
        int moveLeft = circle - game[circle];
        statesToExplore.push(moveRight);
        statesToExplore.push(moveLeft);
    }

    return false;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM