- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
正如标题所说,给定一组数字,我们必须找到总和等于给定数字(我们称之为 M)的所有子集。
你们中的大多数人可能已经熟悉这个问题,所以让我们切入正题。我最近才开始接触回溯编程(我必须告诉你,到目前为止我完全是个半身像),这就是为什么我试图解决更“经典”的问题。
现在,在下方您将看到我的代码试图以回溯方式解决此问题。但是,代码给出了
Exception in thread "main" 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;
}
}
注意:我希望我的评论有用,但如果它们比忽略它们更令人困惑,我认为你可以了解我在没有它们的情况下所做的事情。
尽管如此,我想知道为什么代码会给出该错误(我确实知道通常在什么情况下会给出该错误,但我不明白为什么我会在这里得到它,因为我看不到任何无限循环)以及如何使代码工作,以及它是否回溯。
最佳答案
为了在不出现堆栈溢出错误的情况下找到所有子集,我强烈建议不要使用递归。使用递归通常会在运行时产生大量开销。这种开销会导致堆栈溢出错误。您应该使用称为动态规划的更稳定的算法方法/设计。
Dynamic Programming Example应该向您展示如何利用您当前拥有的东西并将其转化为动态规划概念。
关于java - 回溯 - 给定一组数字,找到和等于 M 的所有子集(M 已给定),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41603263/
在我的类里面,我学习了 Prolog 回溯算法和 Rete forprop 算法,但我也被告知 Rete 可用于进行反向传播。 这是如何运作的?它在哪些方面与 Prolog 回溯相似/不同? 例如,这
两个 friend P1 和 P2 向共同的 friend P3 发送相同的消息 M。 然而由于一些网络损坏,P3 一次只能接收一个字符不知道接收到的字符是属于 P1 还是 P2。 此外,P3 可能会
我最近发了几个理解递归和回溯的问题,我觉得我现在得到了一些东西,并尝试编写一个测试,我确实解决了数独问题,但是当我以另一种格式编写代码时,代码卡了一会儿,返回False,说明这个问题无解。 grid
有人可以指导我或解释如何在 LISP 中执行回溯吗?任何示例或链接将不胜感激。我确实尝试过谷歌,但是他们都没有足够简单的例子让我理解。 谢谢 最佳答案 典型的方法是将不可变状态向下传递到调用堆栈,辅助
我正在使用 apache 2.2.14 运行 Backtrack 5 R2 (ubuntu) 的完全库存安装。我尝试运行一个简单的 index.html 文件,其中包含一些 javascript 代码
如何在 Javascript 中获取回溯? 理想的特征: 入口函数名称,或匿名函数的一些有意义的标识符, 每个级别的参数列表, 行号。 这可以用标准的 ECMAScript 完成吗? 如果没有,是否可
本文首发公众号:小码A梦 回溯算法是一种常见的算法,常见用于解决排列组合、排列问题、搜索问题等算法,在一个搜索空间中寻找所有的可能的解。通过向分支不断尝试获取所有的解,然后找到合适的
Python 是否支持为每个异常/引发/断言显示相同的自定义错误消息(无论代码在哪里中断)? 我目前对它的破解使用了一个装饰器。我有一个函数main它显示回溯很好,但我希望它也打印my_var (在函
输入: 3,4,8,7,3 5,S,7,2,3, 8,5,5,8,10 9,3,3,8,7 6,10,3,G,1 目标是找到从起点(S)到目标(G)的最佳路径。 我们可以向上、向下、向左、向右移动。
我想匹配一个包含“json”(出现超过 2 次)且两个“json”之间没有字符串“from”的字符串。 For example(what I want the string match or not)
我正在尝试使用回溯方法找到熄灯游戏的解决方案。我无法理解此过程的算法。我的方法是枚举从 0 到 2n2 - 1 的所有整数,并将每个整数转换为具有 n*n 位的二进制数。然后,将其分成n2个二进制数字
所以我正在阅读这本书《服从测试山羊》,在学习 Python 时我在第六章中遇到了一个问题。它说我应该能够运行我们在本章和前一章中设置的功能测试,没有错误;但是,我不断收到我不知道如何修复的回溯。 Tr
我需要一些关于 Android 日志文件反混淆的帮助。 问题是如果我有这样的异常: ... 10-16 10:03:10.488: E/AndroidRuntime(25723): Cau
我有一个看起来像这样的表: here | there | -------+-------+ {1,1} | {1,1} | {1,1} | {2,1} | {1,1} | {1,2} |
我写了一小段代码,它应该接受一个字符数组并让它看起来像计算机正在输入文本。很简单,对吧?但是当我运行它时,Terminal 告诉我: *** stack smashing detected ***:
Python 中的堆栈跟踪显示文件路径。有什么方法可以让它们显示完全限定的函数名称吗? 例子: class Foo(object): def bar(self): raise
我决定深入学习回溯的概念,我有以下任务: 给定N个投资者,M个城市,N×M个投资者偏好矩阵P(P[i,j]=1,当第i个投资者希望在第j个城市建矿池;P[i, j] = 0 那么他是中立的,当 P[i
设 E - 图 G 中所有边的集合问题是从G中找到顶点的最小子集S,它满足条件:S = E 中每个顶点的所有出边的总和 换句话说:边是街道,我们可以在顶点上放置路灯。如果我们在一个顶点上放置一盏路灯—
我正在尝试做这个我在查找面试问题时遇到的问题。我们被问及将 r 个硬币放置在 n*m 网格上的方法数量,使得每行和每列至少包含一个硬币。 我想到了一个回溯解决方案,按行主要顺序处理网格中的每个单元格,
我使用 DexGuard混淆。我有来自崩溃日志和映射文件的堆栈跟踪。当我运行 retrace.bat 并为其提供堆栈跟踪和映射文件时,输出仍然是混淆格式。 最佳答案 您是否在使用 ProGuard 的
我是一名优秀的程序员,十分优秀!