Laziale
Laziale

Reputation: 8225

Calculate (complicated) array of decimal numbers in C#

I have a listbox where users can enter decimal numbers. Let's say they'll enter 5 numbers:

1.1
1.2
1.3
1.4 
1.5

I need to get the sum of all the variations in those 5 numbers. For example sum of 1.1 and 1.2 then 1.1 1.2 1.3 then 1.1 1.2 1.3 1.4, then 1.2 1.4 1.5 then 1.1 1.3 1.5.

I started something but that goes through all the variations only skipping one number at a time:

List<Double[]> listNumber = new List<double[]>();            
Double[] array;            
for (int i = 0; i < listBox1.Items.Count; i++)
{
    array = new Double[listBox1.Items.Count];                
    for (int k = 0; k < listBox1.Items.Count; k++)
    {
        if (!k.Equals(i))
        {
            array[k] = (Convert.ToDouble(listBox1.Items[k]));                       
        }
    }
    listNumber.Add(array);
}   

I need to find a way how to calculate the way I want.

Upvotes: 5

Views: 1808

Answers (4)

kmkaplan
kmkaplan

Reputation: 18960

Take your listBox and, in front of each number, either put a 0 to indicate that it will not participate to your sum or a 1 to indicate that it will participate to your sum. With your example list of 1.1, 1.2, 1.3, 1.4, 1.5 and the sums of 1.1, 1.2 then 1.1 1.2 1.3 then 1.1 1.2 1.3 1.4 then 1.2 1.4 1.5 then 1.1 1.3 1.5 this would give you (I only write 1s for clarity, the empty spaces mean 0):

         |     |     | 1.1 |     |
         |     | 1.1 | 1.2 | 1.2 | 1.1
         |     | 1.2 | 1.3 | 1.4 | 1.3
     1.1 | 1.2 | 1.3 | 1.4 | 1.5 | 1.5
---+-----+-----+-----+-----+-----+-----
1.1|  1           1     1           1
1.2|        1     1     1     1
1.3|              1     1           1
1.4|                    1     1
1.5|                          1     1

As you can now see with such a representation, listing all combinations of these numbers is now similar to counting in from 0 to 31 (11111 in binary, 2⁵ - 1). If you are not interested in the empty sequence then start counting from 1.

Here is sample code to transform this counting into an listNumber like you want. Please excuse the syntax as I do not know C#. This also means that this is untested code.

Double[] array = new Double[listBox1.Items.Count];
for (int i = 0; i < listBox1.Items.count; i++)
    array[k] = Convert.ToDouble(listBox1.Items[i]);
int count = 2 ^ array.Items.Count;
List<Double>[] listNumber = new List<Double>[count];
for (int i = 0; i < listNumber.Items.Count; i++) {
    listNumber[i] = new List<Double>();
    for (j = 0; j < array.Items.Count)
        if (i & (1 << j) != 0)
            listNumber[i].Add(array[j]);
}

Upvotes: 0

Kind Contributor
Kind Contributor

Reputation: 18533

In your initial attempt, your code only calculates the sum of all possible pairs. From your description, you also want to find the sum of three numbers, etc..

If there are always 5 decimal numbers, then you can simply have 5 for loops. However a more generic design would be cleaner

double[] input = double[5]; //Pretend the user has entered these
int[] counters = int[input.Length]; //One for each "dimension"
List<double> sums = new List<double>();

for (int i = 0; i < counters.Length; i++)
   counters[i] = -1; //The -1 value allows the process to begin with sum of single digits, then pairs, etc..

while (true)
{
    double thisSum = 0;
    //Apply counters
    for (int i = 0; i < counters.Length; i++)
    {
        if (counters[i] == -1) continue; 

        thisSum += input[counters[i]];
    }

    //Increment counters
    counters[0]++; //Increment at base
    for (int i = 0; i < counters.Length; i++)
    {
        if (counters[i] >= counters.Length)
        {
            if (i == counters.Length - 1) //Check if this is the last dimension
               return sums; //Exhausted all possible combinations

            counters[i] = 0;
            counters[i+1]++;
        }
        else
           break;
    }
}

Here it is without any code for avoiding the addition of the same number twice (I'll let you try to finish that off. HINT: You can simply do so after the increment counters section, containing both the "Increment Counters" section and the new "Check Counters" section inside a while loop, breaking outside the while loop when the counters are unique...

NOTE: I haven't tested this code, but it'll be close, and will likely have one or two bugs in it - let me know if you need any help with the bugs.

Upvotes: 1

Rawling
Rawling

Reputation: 50114

Just an outline as I'm on my phone:

Start with your input list and an output list that contains a zero.

For each number in your input, create a new list of doubles by adding the current input number to each of the numbers in the current output list; then concatenate this list to the end of the output list.

Optionally, remove the zero and the first instance of each of the input numbers, and any duplicates:

E.g. for your example input up to 1.4:

0
0 1.1
0 1.1 1.2 2.3
0 1.1 1.2 2.3 1.3 2.4 2.5 3.6
0 1.1 1.2 2.3 1.3 2.4 2.5 3.6 1.4 2.5 2.6 3.7 2.7 3.8 3.9 5.0
         1.2 2.3      2.4 2.5 3.6         2.6 3.7 2.7 3.8 3.9 5.0                    

Upvotes: 1

Isi
Isi

Reputation: 41

While I'm not very proficient in C#, I'm positively sure there's a much more simple way of doing what you want to do; unless of course, I'm missing something.

Why not make a for loop for every element in the List or Array, and then tell it to skip itself. Example:

Double[] array = new Double[3];
array[0] = 1,1;
array[1] = 1,2;
array[2] = 1,3;

Double sum = 0;

for ( int i = 0; i < array.Length ; i++ )
{
    for ( int x = 0 ; x < array.Length ; x++ ) {
        if ( array[i] != array[x] )
        {
            sum = array[x] + array[x+1] // or [x-1] depending on the value of x, you should be able to work this out.   
        }
    }
}

You should be able to understand what I mean by examining this example. Of course, this is a very basic prototype, what you'll do is expand this to check backwards depending on the value of x, and to have multiple "sum" variables to store your sums - depending on what kind of results you're looking for.

-I hope this helps, Merry Christmas.

Upvotes: 0

Related Questions