如何修复我的代码以编写SubSet Sum问题解决方案的变体?

时间:2019-01-13 13:01:18

标签: java arrays algorithm subset-sum array-algorithms

考虑子集总和(SUSU)问题,我需要编写类中显示的解决方案的变体,该变体还将打印汇总哪些权重以达到给定的总和。例如,如果:

sum=12;
int[] weights={1,7,9,3};

输出将是:0011也就是说,对于权重中的每个值,如果添加了该值,则我们将其写入“ 1”,否则将其写入“ 0”。

在朋友的帮助下,我编写了以下代码:

    public static void main(String[] args) {

    int[] arr={9,1,7,3};
    System.out.println(Arrays.toString(SubsetSum(arr,12)));
}   

public static int[] SubsetSum(int[] arr, int sum){
    int[] output= new int[arr.length];
    return SubsetSum(arr,sum, 0, output);
}

public static int[] SubsetSum(int[] arr, int sum, int index, int[]weights){
    int[] output= new int[arr.length];
    if(sum==0)
        return weights;
    if(sum<0 | index>=arr.length)
        return output;
    weights[index]=0;
    int[] arr1= SubsetSum(arr,sum,index+1, weights);
    weights[index]=1;
    int[]arr2=SubsetSum(arr,sum-arr[index],index+1,weights);
    boolean isZero=true;
    for(int i=0; i<arr1.length & isZero; i=i+1)
        if(arr1[i]!=0)
            isZero=true;
    if(isZero)
        return arr2;
    else
        return arr1;
}

我希望SubsetSum(arr,12)的输出为[1、0、0、1],但实际输出为[0、0、0、0]。 我知道为什么它会从我的代码中返回此输出,但是我不知道如何解决它。

1 个答案:

答案 0 :(得分:0)

我更改了返回结果的方法。现在使用的项目以used参数的位进行编码。

Ideone

Main打印项目的索引(如果失败,则不打印任何内容)-例如1,2,3,即1 + 7 + 13

我对Java不熟悉,因此请代表结果以便更好地查看(也许像inttobinary之类的东西)

public static void main(String[] args) {

    int[] arr={9,1,7,13,3};
    int i = 0;
    int res = SubsetSum(arr, 21, 0, 0);
    while (res > 0) {
        if ((res & 1) > 0) 
            System.out.println(i);
        i++;
        res >>= 1;
    }       
}   

public static int SubsetSum(int[] arr, int sum, int index, int used){
    if(sum==0)
        return used;
    if(sum<0 | index>=arr.length)
        return 0;
       int a = SubsetSum(arr,sum,index+1, used);
       int b = SubsetSum(arr,sum-arr[index],index+1, used | (1 << index));
       if (a > 0)
          return a;
       else
          return b;
}  
}

P.S。代码中存在缺陷:
isZero从未更改。
如果您更正逻辑以返回非零数组,则它将用全1填充-可能是因为weights[index]=1;通过公共引用更改了同一数组实例(不知道Java术语)。在我的代码中,每个递归级别都有一个used实例,修改其位不会影响其他分支中的值。