简体   繁体   English

所有可能的数组子集的乘积之和

[英]Sum of product of all possible subsets of array

I have written a code to find Sum of product of all possible subsets of array. 我编写了一个代码来查找所有可能的数组子集的乘积。 I'm getting the expected output but I'm not able to make it fast enough to clear time related test cases. 我得到了预期的输出但是我无法让它足够快以清除时间相关的测试用例。

Can anyone help me in optimizing my code for speed? 任何人都可以帮助我优化代码的速度吗?

First input (testCases) is the number of testcases. 第一个输入(testCases)是测试用例的数量。 Depending on number of testcase, we will have size of array (size) and array elements (set). 根据测试用例的数量,我们将具有数组(大小)和数组元素(集合)的大小。

For example, a valid input would be: 例如,有效输入将是:

1
3
2 3 5

where: 哪里:

1 is the number of testcases. 1是测试用例的数量。 3 is the size of the test set and 2 3 5 are the elements of the input set. 3是测试集的大小, 2 3 5是输入集的元素。

The expected output is: 预期的产出是:

71

The calculation for the above output is: 上述输出的计算如下:

    {2}, {3}, {5}, {2, 3}, {3, 5}, {2, 5}, {2, 3, 5}

=>   2    3    5      6      15      10        30

=>   2 + 3 + 5 + 6 + 15 + 10 + 30

=>   71

import java.util.Scanner;

public class Test {
    static int printSubsets(int set[]) {
        int n = set.length;
        int b = 0;

        for (int i = 0; i < (1 << n); i++) {
            int a = 1;
            for (int j = 0; j < n; j++){

                if ((i & (1 << j)) > 0) {

                    a *= set[j];
                }}

            b += a;
        }
        return b;
    }

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        int testCases = scanner.nextInt();

        for (int i = 0; i < testCases; i++) {
            int size = scanner.nextInt();
            int set[] = new int[size];
            for (int j = 0; j < set.length; j++) {
                set[j] = scanner.nextInt();
            }

            int c = printSubsets(set);
            System.out.println((c - 1));

        }
        scanner.close();
    }
}

You need to use a little math. 你需要使用一点数学。 Lets say you have 3 values, like your example, but lets call them A , B , and C . 假设您有3个值,就像您的示例一样,但我们称之为ABC

To get sum of products, you need to calculate: 要获得产品总和,您需要计算:

Result3 = A + B + C + A*B + A*C + B*C + A*B*C
        = A + B + A*B + (1 + A + B + A*B) * C

Now, if we calculate A + B + A*B first, calling it Result2 , then you get: 现在,如果我们首先计算A + B + A*B ,将其Result2 ,那么你得到:

Result2 = A + B + A*B
Result3 = Result2 + (1 + Result2) * C

And we repeat that, so 我们重复一遍,所以

Result2 = A + (1 + A) * B
Result1 = A
Result2 = Result1 + (1 + Result1) * B

Can you see the pattern? 你能看到这种模式吗? Let's use that with 4 values: 让我们使用4个值:

Result4 = A + B + C + D + A*B + A*C + A*D + B*C + B*D + C*D
        + A*B*C + A*B*D + A*C*D + B*C*D + A*B*C*D
        =      A + B + C + A*B + A*C + B*C + A*B*C
        + (1 + A + B + C + A*B + A*C + B*C + A*B*C) * D
        = Result3 + (1 + Result3) * D

Summary: 摘要:

Result1 = A
Result2 = Result1 + (1 + Result1) * B
Result3 = Result2 + (1 + Result2) * C
Result4 = Result3 + (1 + Result3) * D

As code, this is: 作为代码,这是:

private static long sumProduct(int... input) {
    long result = 0;
    for (int value : input)
        result += (result + 1) * value;
    return result;
}

Only one iteration, so O(n) . 只有一次迭代,所以O(n)

Test 测试

System.out.println(sumProduct(2, 3));
System.out.println(sumProduct(2, 3, 5));
System.out.println(sumProduct(2, 3, 5, 7));

Output 产量

11
71
575

UPDATE UPDATE

Code can also be done using Java 8 Streams with a Lambda expression, using either IntStream.of(int...) or Arrays.stream(int[]) (they do the same). 代码也可以使用带有Lambda表达式的Java 8 Streams,使用IntStream.of(int...)Arrays.stream(int[]) (它们执行相同的操作)来完成。

// Using IntStream with result as int
private static int sumProduct(int... input) {
    return IntStream.of(input).reduce((a, b) -> a + (1 + a) * b).getAsInt();
}
// Using Arrays with result as long
private static long sumProduct(int... input) {
    return Arrays.stream(input)
                 .asLongStream()
                 .reduce((a, b) -> a + (1 + a) * b)
                 .getAsLong();
}

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM