简体   繁体   English

回溯 - 给定一组数字,找到总和等于 M 的所有子集(给定 M)

[英]Backtracking - Given a set of numbers, find all the subsets with a sum equal to M (M is given)

As the title says, we are given a set of numbers and we have to find all the subsets with a sum equal to a given number(we'll call it M).正如标题所说,我们得到一组数字,我们必须找到总和等于给定数字的所有子集(我们称之为 M)。

Most of you are probably familiar with the problem already, so let's cut to the chase.你们中的大多数人可能已经熟悉这个问题,所以让我们切入正题。 I have just recently gotten into backtracking programing (I gotta tell you that I'm a complete bust so far), that's why I am trying to solve the more "classic" problems.我最近才开始回溯编程(我得告诉你,到目前为止我是一个彻头彻尾的人),这就是为什么我试图解决更“经典”的问题。

Now, down below you will see my code that tries to solve this problem, in a backtracking fashion.现在,在下面你会看到我的代码,它试图以回溯的方式解决这个问题。 However, the code gives但是,代码给出

Exception in thread "main" java.lang.StackOverflowError线程“main”中的异常 java.lang.StackOverflowError

on line 44(I shall have it highlighted) and also, I don't really know if it really solves the problem in a backtracking way or if my code is just complete and utter poop.在第 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;
    }

}

NOTE: I hope that my comments are useful, but if they are more confusing than helping just ignore them, I think that you can get an idea of what I'm doing without them.注意:我希望我的评论有用,但如果它们比帮助忽略它们更令人困惑,我认为您可以了解没有它们我在做什么。

Nevertheless, I would like to find out why is it that the codes gives that error(I do know under what context that error is generally given, I do not understand however why I get it here, as I can't see any endless loop) and how to make the code work, and also whether or not it is backtracking.尽管如此,我想找出代码给出该错误的原因(我确实知道在什么情况下通常会给出该错误,但我不明白为什么我在这里得到它,因为我看不到任何无限循环) 以及如何使代码工作,以及它是否正在回溯。

In order to find all the subsets without reaching a stack overflow error I would highly recommend staying clear of recursion.为了在不出现堆栈溢出错误的情况下找到所有子集,我强烈建议不要使用递归。 Using recursion will typically generate a lot of overhead during runtime.使用递归通常会在运行时产生大量开销。 This overhead tneds to lead to stack overflow errors.这种开销会导致堆栈溢出错误。 You should use a more stable algorithmic approach/design called dynamic programming.您应该使用更稳定的算法方法/设计,称为动态规划。

Dynamic Programming Example should show you how to take what you currently have and translate it to the dynamic programming concept. 动态编程示例应该向您展示如何获取您当前拥有的内容并将其转换为动态编程概念。

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

相关问题 给定一个整数数组和一个总和,任务是找出给定数组的子集是否存在总和等于给定总和的子集 - Given an array of integers and a sum, the task is to find if there exists a subsets of given array with sum equal to given sum 查找具有给定总和的数字子集 - Finding Subsets of Numbers with a Given Sum 打印出一个递归等于给定和的数组中的所有子集 - Print out all subsets in an array that equal an given sum recursively 递归打印数组中等于给定总和的所有子集 - Print all subsets in an array that equal to a given sum recursively 给定一个数组,找到总和为值k的所有子集 - Given an array, find all subsets which sum to value k 使用不同的二进制数查找给定集合的子集 - Using distinct binary numbers to find subsets of a given set 给定一组n个整数,返回总和为0的k个元素的所有子集 - given a set of n integers, return all subsets of k elements that sum to 0 仅使用集合中的数字找到等于或大于给定目标的总和 - Find a sum equal or greater than given target using only numbers from set 动态编程-打印给定总和的所有子集 - dynamic programming - print all subsets with the given sum 递归打印出等于给定总和的数组中的所有子集不会跳转到下一个迭代 - Print out all subsets in an array that equal an given sum recursively does not jump to the next iteration
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM