在C#中计算(复杂)十进制数组

时间:2012-12-26 00:15:04

标签: c# arrays list math arraylist

我有一个列表框,用户可以输入十进制数字。假设他们将输入5个数字:

1.1
1.2
1.3
1.4 
1.5

我需要得到这5个数字中所有变化的总和。例如1.1 and 1.2然后1.1 1.2 1.3然后1.1 1.2 1.3 1.4,然后1.2 1.4 1.5然后1.1 1.3 1.5的总和。

我开始了一些事情,但是所有变化只会一次跳过一个数字:

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);
}   

我需要找到一种方法来计算我想要的方式。

4 个答案:

答案 0 :(得分:1)

我手机上的大纲:

从输入列表和包含零的输出列表开始。

对于输入中的每个数字,通过将当前输入数字添加到当前输出列表中的每个数字来创建新的双打列表;然后将此列表连接到输出列表的末尾。

(可选)删除每个输入数字的零和第一个实例,以及任何重复项:

E.g。为您的示例输入最多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                    

答案 1 :(得分:1)

在您的初始尝试中,您的代码仅计算所有可能对的总和。根据您的描述,您还希望找到三个数字的总和等。

如果总有5个十进制数,那么你只需要5个for循环。然而,更通用的设计将更清洁

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;
    }
}

这里没有任何代码可以避免两次添加相同的数字(我会让你试着完成它。提示:你可以在增量计数器部分后执行此操作,包含“增量计数器”)一个while循环中的section和新的“Check Counters”部分,当计数器是唯一的时,在while循环之外突破......

注意:我没有测试过这段代码,但它会很接近,并且可能会有一两个错误 - 如果您需要任何有关错误的帮助,请告诉我。

答案 2 :(得分:0)

虽然我对C#不是很精通,但我确信有一种更简单的方法可以做你想做的事情。除非当然,我错过了一些东西。

为什么不为List或Array中的每个元素创建一个for循环,然后告诉它跳过它自己。 例如:

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.   
        }
    }
}

通过检查这个例子你应该能够理解我的意思。 当然,这是一个非常基本的原型,你要做的是扩展它以根据x的值向后检查,并有多个“sum”变量来存储你的总和 - 取决于你是什么样的结果寻找。

- 我希望这会有所帮助,圣诞快乐。

答案 3 :(得分:0)

抓住你的listBox,并在每个号码前加0表示参与你的总和或1表示参与您的金额。您的示例列表包含1.11.21.31.41.5以及1.11.2的总和1.1 1.2 1.3然后1.1 1.2 1.3 1.4然后1.2 1.4 1.5然后1.1 1.3 1.5这会给你(为了清晰起见我只写1,空格意味着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

正如您现在可以看到的那样,列出这些数字的所有组合现在类似于从0到31计数(二进制中的11111,2⁵ - 1)。如果您对空序列不感兴趣,则从1开始计数。

以下是将此计数转换为您想要的listNumber的示例代码。请原谅我不知道C#的语法。这也意味着这是未经测试的代码。

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]);
}