algorithm to sum up a list of numbers for all combinations

前端 未结 15 2257
北荒
北荒 2020-12-04 22:34

I have a list of numbers and I want to add up all the different combinations. For example:

  • number as 1,4,7 and 13
  • the output would be:

相关标签:
15条回答
  • 2020-12-04 23:08

    This is not the code to generate the sums, but it generates the permutations. In your case:

    1; 1,4; 1,7; 4,7; 1,4,7; ...

    If I have a moment over the weekend, and if it's interesting, I can modify this to come up with the sums.

    It's just a fun chunk of LINQ code from Igor Ostrovsky's blog titled "7 tricks to simplify your programs with LINQ" (http://igoro.com/archive/7-tricks-to-simplify-your-programs-with-linq/).

    T[] arr = …;
    var subsets = from m in Enumerable.Range(0, 1 << arr.Length)
                  select
                      from i in Enumerable.Range(0, arr.Length)
                      where (m & (1 << i)) != 0
                      select arr[i];
    
    0 讨论(0)
  • 2020-12-04 23:09
    v=[1,2,3,4]#variables to sum
    i=0
    clis=[]#check list for solution excluding the variables itself
    def iterate(lis,a,b):
        global i
        global clis
        while len(b)!=0 and i<len(lis):
            a=lis[i]
            b=lis[i+1:]
            if len(b)>1:
                t=a+sum(b)
                clis.append(t)
            for j in b:
                clis.append(a+j)
            i+=1
            iterate(lis,a,b)
    iterate(v,0,v)
    

    its written in python. the idea is to break the list in a single integer and a list for eg. [1,2,3,4] into 1,[2,3,4]. we append the total sum now by adding the integer and sum of remaining list.also we take each individual sum i.e 1,2;1,3;1,4. checklist shall now be [1+2+3+4,1+2,1+3,1+4] then we call the new list recursively i.e now int=2,list=[3,4]. checklist will now append [2+3+4,2+3,2+4] accordingly we append the checklist till list is empty.

    0 讨论(0)
  • 2020-12-04 23:09

    set is the set of sums and list is the list of the original numbers.

    Its Java.

    public void subSums() {
        Set<Long> resultSet = new HashSet<Long>();
        for(long l: list) {
            for(long s: set) {
                resultSet.add(s);
                resultSet.add(l + s);
            }
            resultSet.add(l);
            set.addAll(resultSet);
            resultSet.clear();
        }
    }
    
    0 讨论(0)
  • 2020-12-04 23:11

    The best-known algorithm requires exponential time. If there were a polynomial-time algorithm, then you would solve the subset sum problem, and thus the P=NP problem.

    The algorithm here is to create bitvector of length that is equal to the cardinality of your set of numbers. Fix an enumeration (n_i) of your set of numbers. Then, enumerate over all possible values of the bitvector. For each enumeration (e_i) of the bitvector, compute the sum of e_i * n_i.

    The intuition here is that you are representing the subsets of your set of numbers by a bitvector and generating all possible subsets of the set of numbers. When bit e_i is equal to one, n_i is in the subset, otherwise it is not.

    The fourth volume of Knuth's TAOCP provides algorithms for generating all possible values of the bitvector.

    0 讨论(0)
  • 2020-12-04 23:13

    Here's how a simple recursive solution would look like, in Java:

    public static void main(String[] args)
    {
        f(new int[] {1,4,7,13}, 0, 0, "{");
    }
    
    static void f(int[] numbers, int index, int sum, String output)
    {
        if (index == numbers.length)
        {
            System.out.println(output + " } = " + sum);
            return;
        }
    
        // include numbers[index]
        f(numbers, index + 1, sum + numbers[index], output + " " + numbers[index]);
    
        // exclude numbers[index]
        f(numbers, index + 1, sum, output);
    }
    

    Output:

    { 1 4 7 13 } = 25
    { 1 4 7 } = 12
    { 1 4 13 } = 18
    { 1 4 } = 5
    { 1 7 13 } = 21
    { 1 7 } = 8
    { 1 13 } = 14
    { 1 } = 1
    { 4 7 13 } = 24
    { 4 7 } = 11
    { 4 13 } = 17
    { 4 } = 4
    { 7 13 } = 20
    { 7 } = 7
    { 13 } = 13
    { } = 0
    
    0 讨论(0)
  • 2020-12-04 23:13

    C#:

    I was trying to find something more elegant - but this should do the trick for now...

    //Set up our array of integers
    int[] items = { 1, 3, 5, 7 };
    
    //Figure out how many bitmasks we need... 
    //4 bits have a maximum value of 15, so we need 15 masks.
    //Calculated as:
    //    (2 ^ ItemCount) - 1
    int len = items.Length;
    int calcs = (int)Math.Pow(2, len) - 1;
    
    //Create our array of bitmasks... each item in the array
    //represents a unique combination from our items array
    string[] masks = Enumerable.Range(1, calcs).Select(i => Convert.ToString(i, 2).PadLeft(len, '0')).ToArray();
    
    //Spit out the corresponding calculation for each bitmask
    foreach (string m in masks)
    {
        //Get the items from our array that correspond to 
        //the on bits in our mask
        int[] incl = items.Where((c, i) => m[i] == '1').ToArray();
    
        //Write out our mask, calculation and resulting sum
        Console.WriteLine(
            "[{0}] {1}={2}", 
            m, 
            String.Join("+", incl.Select(c => c.ToString()).ToArray()), 
            incl.Sum()
        );
    }
    

    Outputs as:

    [0001] 7=7
    [0010] 5=5
    [0011] 5+7=12
    [0100] 3=3
    [0101] 3+7=10
    [0110] 3+5=8
    [0111] 3+5+7=15
    [1000] 1=1
    [1001] 1+7=8
    [1010] 1+5=6
    [1011] 1+5+7=13
    [1100] 1+3=4
    [1101] 1+3+7=11
    [1110] 1+3+5=9
    [1111] 1+3+5+7=16
    
    0 讨论(0)
提交回复
热议问题