正如標題所說,我們得到一組數字,我們必須找到所有子集的總和相等到給定的數字(我們稱它爲M)。回溯 - 給定一組數字,找出總和等於M的所有子集(M給出)
你們中的大多數人可能已經對這個問題很熟悉了,所以讓我們開始追逐。我最近剛剛進入回溯計劃(我得告訴你,我到目前爲止已經完全崩潰了),這就是爲什麼我想要解決更多「經典」問題。
現在,在下面你會看到我的代碼試圖以回溯的方式解決這個問題。但是,代碼給出線程
異常「主要」 java.lang.StackOverflowError的
第44行(我有它突出顯示),還,我真的不知道,如果它真的以回溯方式解決問題,或者如果我的代碼只是完整和徹底的便便。
package project3;
import java.util.*;
public class Main {
static int[] A = { 1, 2, 3, 4 }; // the array in which we are given the numbers.->
static int n = A.length; // -> I have it filled with 1, 2, 3, 4 for testing purposes
static int m = 5; // the number which the subsets' sum must be
static int[] Sol = new int[50]; // the array in which solutions are stored up->
//->until they are syso'ed, after that it gets zero'ed
static void makeZero() { // make the solution array 0 again
for (int i = 0; i < 50; i++)
Sol[i] = 0;
}
static void show() { // outputs the solution array
int i = 0;
while (Sol[i] != 0 && i < 49) {
System.out.print(Sol[i] + " ");
i++;
}
}
public static void main(String[] args) {
Sol[0]=A[0]; back(0, 1, A[0], 1);// we start with the first number in the array as->
} // -> both the first element as the solution and part of the sum
static int back(int i, int j, int S, int nr) {
if (i < n && j < n) {
if (A[j] + S == m) {// if we got a solution, we output it and then go to the ->
Sol[nr] = A[j]; // -> next element if possible, if not, we start again with ->
show(); // -> the following element
if (j < n - 1)
back(i, j++, S, nr);
else if (i < n - 1) {
makeZero();
back(i + 1, i + 2, 0, 0);
}
}
else if (A[j] + S > m) { // condition for stoping and starting over with another element
if (j < n - 1) // we try again with the following element
back(i, j++, S, nr);// LINE 44 : Exception in thread "main" java.lang.StackOverflowError
else if (i < n - 2 && j == n - 1) { // if not possible, we start again with the following element
makeZero();
back(i + 1, i + 2, 0, 0);
} else if (i == n - 2 && j == n - 1) // if we are down to the last element->
if (A[i + 1] == m) // ->we check if it is ==m
System.out.println(A[i + 1]);
}
else if (j < n - 1 && A[j] + S < m) { // obvious
Sol[nr++] = A[j];
S = S + A[j];
back(i, j + 1, S, nr);
}
else if (j == n - 1 && A[j] + S < m && i < n - 2) {// if the sum!=m and the are no more elements->
makeZero(); // ->start again with another element
back(i + 1, i + 2, 0, 0);
}
else { // if we are down to the last element, we check if it is ==m
if(A[i+1]==n-1)
System.out.println(A[i + 1]);
}
}
return 0;
}
}
注:我希望我的意見是有益的,但如果他們是不是幫助不理會他們更加混亂,我認爲你可以得到做什麼我沒有他們的想法。然而,我想知道爲什麼代碼給出了這個錯誤(我知道在什麼情況下通常給出錯誤,但我不明白爲什麼我在這裏得到它,因爲我不能看到任何無限循環)以及如何使代碼工作,以及它是否回溯。
它在程序的運行時堆棧中的內存量運行到其最大容量時發生。實現這個錯誤的最簡單方法是使用遞歸,通過一次又一次地調用一個函數中的函數而不返回而不斷地將東西推到運行時堆棧上。這是你連續調用back()所做的。 –
@RAZ_Muh_Taz我編輯了最後一部分。 –
首先,我會使用一個隊列,然後從達到「50」數量限制而不是大小爲50的數組中取出。此外,您還給它一個1的「最壞情況」,因爲總和在你的數組中的任何數字永遠不會加起來1,這將解釋堆棧溢出和大量的調用返回() –