Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 编写一个算法,为解决方案解决给定数字的所有可能组合_Java_Algorithm_List - Fatal编程技术网

Java 编写一个算法,为解决方案解决给定数字的所有可能组合

Java 编写一个算法,为解决方案解决给定数字的所有可能组合,java,algorithm,list,Java,Algorithm,List,其思想是,有一个可以多次使用的数字列表(如果解是5,列表是(1,4,2),那么可能的解是(1,1,1,1,1)(1,4)(1,2,2)(4,1)(2,1,1,1)(2,1,2)(2,1,2,1) 我目前的代码是: static void J5(int distance, ArrayList<Integer> p) { for (int i=0; i < p.size(); i++) { int sub = (distance - p.get(i)

其思想是,有一个可以多次使用的数字列表(如果解是5,列表是(1,4,2),那么可能的解是(1,1,1,1,1)(1,4)(1,2,2)(4,1)(2,1,1,1)(2,1,2)(2,1,2,1)

我目前的代码是:

static void J5(int distance, ArrayList<Integer> p)
{
    for (int i=0; i < p.size(); i++)
    {
        int sub = (distance - p.get(i));

        if (sub == 0)
        {
            System.out.print(p.get(i) + "\n");
            return;
        }
        if (sub < 0)
        {
            sub = distance - p.get(i);      
        }
        if (sub > 0)
        {
            System.out.print(p.get(i) + " ");
            J5(sub, p);
        }
    }
}
因此,在这个例子中,唯一完全正确的是第一次迭代,2+2+1=5,但是下一次应该是(2,1,2)
尽管每个元素都可以多次使用,但也没有(1,1,1,1,1)元素。

代码实际上可以工作。您只是误解了它。只需在输出中添加一点结构,您就会注意到:

static void J5(int distance, String indent , ArrayList<Integer> p)
{
    for(int i=0; i < p.size();i++)
    {
        int sub = (distance - p.get(i));

        if (sub == 0)
        {
            System.out.println(indent + p.get(i)+ " Solution found" + "\n");

            return;
        }else if (sub > 0)
        {
            System.out.println(indent + p.get(i)+ " " + " distance remaining: " + sub);
            J5(sub , indent + "\t" , p);
        }
    }
}
将其视为一种树。缩进显示递归深度,这相当于每个节点的级别。整个路径包含完整的解决方案。每个“找到的解决方案”将相当于代码示例输出中的一行新行

该算法工作得很好,只要找到一个有效的解决方案,它就不会打印所有找到的数字

关于代码本身的几点注意事项:代码中的第二个
if
-子句是无用的。对
sub
所做的修改将被丢弃而不被使用,并且其中没有其他修改。此算法需要一个排序的列表作为输入,如果要使用它,您必须考虑到这一点代码

至于解决方案本身:只需将目前生成的解决方案作为参数保留到下一次调用:

void J5(int distance , ArrayList<Integer> p , String solution){
    ...
    if(sub == 0){
        System.out.println(solution + " " + p.get(i));
    }else if(sub > 0){
        J5(sub , p , solution + p.get(i));
    }
}
void J5(整数距离,数组列表p,字符串解决方案){
...
如果(sub==0){
System.out.println(解决方案+“”+p.get(i));
}否则,如果(子>0){
J5(sub,p,solution+p.get(i));
}
}

至于缺少的“1”-输出:对我来说效果很好。

这里我为您写了一个简洁明了的解决方案:

public class Test {
    static void combinationSumUtils(int indx, int sum, ArrayList<Integer> candidates, ArrayList<Integer> solution) {
        if(indx == candidates.size()) {
            if(sum == 0) {
                for(int i = 0; i < solution.size(); ++i) {
                    System.out.print(solution.get(i) + " ");
                }
                System.out.println();
            }
            return;
        }
        if(sum == 0) {
            for(int i = 0; i < solution.size(); ++i) {
                System.out.print(solution.get(i) + " ");
            }
            System.out.println();
            return;
        }
        for(int i = 0; i < candidates.size(); ++i) {
            if(sum - candidates.get(i) >= 0) {
                solution.add(candidates.get(i));
                combinationSumUtils(i, sum - candidates.get(i), candidates, solution);
                solution.remove(solution.size() - 1);
            } else {
                break;
            }
        }
    }

    public static void main(String[] args) {
        ArrayList<Integer> solution = new ArrayList<Integer>();
        ArrayList<Integer> candidates = new ArrayList<Integer>();
        candidates.add(1);
        candidates.add(4);
        candidates.add(2);
        Collections.sort(candidates);
        combinationSumUtils(0, 5, candidates, solution);
    }
}

等效C++解决方案:

void combinationSumUtils(int indx, int sum, vector<int> &candidates, vector<int> &solution, vector<vector<int> > &result) {
        if(indx == candidates.size()) {
            if(sum == 0) result.push_back(solution);
            return;
        }
        if(sum == 0) {
            result.push_back(solution);
            return;
        }
        for(int i = 0; i < candidates.size(); ++i) {
            if(sum - candidates[i] >= 0) {
                solution.push_back(candidates[i]);
                combinationSumUtils(i, sum - candidates[i], candidates, solution, result);
                solution.pop_back();
            } else {
                break;
            }
        }
    }

    vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
        vector<vector<int> > result;
        vector<int> solution;
        if(candidates.size() < 0) return result;
        sort(candidates.begin(), candidates.end());
        combinationSumUtils(0, target, candidates, solution, result);
        return result;
    }
void组合sumultils(int indx、int sum、向量和候选者、向量和解、向量和结果){
if(indx==candidates.size()){
如果(总和==0)结果,则返回(解决方案);
返回;
}
如果(总和=0){
结果:推回(解决方案);
返回;
}
对于(int i=0;i=0){
解决方案。推回(候选[i]);
组合sumultils(i,sum-候选者[i],候选者,解,结果);
解决方案。弹出返回();
}否则{
打破
}
}
}
向量组合和(向量和候选,int目标){
矢量结果;
向量解;
if(candidates.size()<0)返回结果;
排序(candidates.begin()、candidates.end());
组合汇总(0,目标,候选项,解决方案,结果);
返回结果;
}

您应该引入一个新变量,并在递归期间将当前答案存储在那里,然后将其打印在
sub==0
中。您所说的当前答案是什么意思?一旦调用递归,它不会丢失吗?所以将其传递给递归-添加一个新参数。这很好,但不幸您使用了错误的语言。Op我用Java解决方案更新了我的答案。谢谢:)真有趣。编码服务得到了投票,发现错误的解决方案被忽略了……我没有看到你的答案,我更欣赏你的答案而不是我的答案,我已经放弃了投票。我发现问题中的代码有点杂乱无章,这就是为什么我计划提供一个精确而清晰的代码片段。您指出了他的代码中的错误,这显然对他更有利。我认为你的回答应该被接受:)@KaidulIslam谢谢。只是觉得这种行为有点奇怪。
public class Test {
    static void combinationSumUtils(int indx, int sum, ArrayList<Integer> candidates, ArrayList<Integer> solution) {
        if(indx == candidates.size()) {
            if(sum == 0) {
                for(int i = 0; i < solution.size(); ++i) {
                    System.out.print(solution.get(i) + " ");
                }
                System.out.println();
            }
            return;
        }
        if(sum == 0) {
            for(int i = 0; i < solution.size(); ++i) {
                System.out.print(solution.get(i) + " ");
            }
            System.out.println();
            return;
        }
        for(int i = 0; i < candidates.size(); ++i) {
            if(sum - candidates.get(i) >= 0) {
                solution.add(candidates.get(i));
                combinationSumUtils(i, sum - candidates.get(i), candidates, solution);
                solution.remove(solution.size() - 1);
            } else {
                break;
            }
        }
    }

    public static void main(String[] args) {
        ArrayList<Integer> solution = new ArrayList<Integer>();
        ArrayList<Integer> candidates = new ArrayList<Integer>();
        candidates.add(1);
        candidates.add(4);
        candidates.add(2);
        Collections.sort(candidates);
        combinationSumUtils(0, 5, candidates, solution);
    }
}
1 1 1 1 1 
1 1 1 2 
1 1 2 1 
1 2 1 1 
1 2 2 
1 4 
2 1 1 1 
2 1 2 
2 2 1 
4 1
void combinationSumUtils(int indx, int sum, vector<int> &candidates, vector<int> &solution, vector<vector<int> > &result) {
        if(indx == candidates.size()) {
            if(sum == 0) result.push_back(solution);
            return;
        }
        if(sum == 0) {
            result.push_back(solution);
            return;
        }
        for(int i = 0; i < candidates.size(); ++i) {
            if(sum - candidates[i] >= 0) {
                solution.push_back(candidates[i]);
                combinationSumUtils(i, sum - candidates[i], candidates, solution, result);
                solution.pop_back();
            } else {
                break;
            }
        }
    }

    vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
        vector<vector<int> > result;
        vector<int> solution;
        if(candidates.size() < 0) return result;
        sort(candidates.begin(), candidates.end());
        combinationSumUtils(0, target, candidates, solution, result);
        return result;
    }