[英]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.