solving stackoverflowException in a recursive method
I have written a method for my homework to compute all of the permutations of a array of integer numbers with recursion. ( I am trying to implement backtracking algorithm). but it cause StackOverflowException
for computing the premutaions of more than 7 numbers. I dont know how to solve this problem. does it still implement backtracking if I use itration?
code:
solve(0, arr, currentS);
//****************
private static void solve(int i, ArrayList<Integer> arr, int[] currentS) {
if (i == arr.size()) {
for (int j : currentS) {
System.out.print(j + ",");
}
System.out.println();
currentS[i-1] = 0;
solve(i - 2, arr, currentS);
} else {
int x = nextValue(i, currentS, arr);
if (x != -1&&travers.isCompatible(arr, currentS.clone())) {
currentS[i] = x;
solve(i + 1, arr, currentS);
}
else if((i != 0))
{
currentS[i] = 0;
solve(i - 1, arr, currentS);
}
}
return;
}
nextValue()
is method that check not to have duplicate in the children of a node of tree, of not to have duplicate from root to each leave
exception:
Exception in thread "开发者_运维百科main" java.lang.StackOverflowError
at java.util.ArrayList.get(Unknown Source) ....
Not to disillusion you, but my solution for this question has 14 lines of code. Perhaps you should rethink your approach.
Hint: You don't really need a separate list to hold the current permutation, you can permute (and unpermute) the array directly. That means you won't need any code to detect duplicates in the list.
But your problem is probably more basic. Wikipedia writes:
A recursive function definition has one or more base cases, meaning input(s) for which the function produces a result trivially (without recurring), and one or more recursive cases, meaning input(s) for which the program recurs (calls itself). For example, the factorial function can be defined recursively by the equations 0! = 1 and, for all n > 0, n! = n(n − 1)!. Neither equation by itself constitutes a complete definition; the first is the base case, and the second is the recursive case. The job of the recursive cases can be seen as breaking down complex inputs into simpler ones. In a properly-designed recursive function, with each recursive call, the input problem must be simplified in such a way that eventually the base case must be reached.
(emphasis mine). I don't see any attempt to guarantee that i == arr.length
will ever be reached. Sometimes i gets smaller when recursing, sometimes it gets larger, it's quite possible that it'll simply oscillate without ever reaching the base case. Put differently, your program would never terminate, but since each recursion step needs additional memory, you run out of stack space.
Assuming that your algorithm is sound and works correctly for 7 numbers ...
Then what you may need is more stack space. This can be done on the Java command line by adding "-Xss1024k" for a 1 meg stack size. You can increase that more for more space. Doing so may give you what you need.
However, you must understand, there is ALWAYS an upper bound for stack space and a recursive algorithm will risk hitting that upper bound. You may be better off using a different algorithm that doesn't use the call stack to store the work you need to do. Sometimes it's better to use the heap space instead with something like an instance of a Queue or Stack class to hold your state.
精彩评论