我有一个十元素的整数数组。我想按组对元素求和,所以例如我想在元素0处添加值,元素1的值,然后是元素2的值,然后是3,依此类推到元素9,然后添加元素1处的值,其值为2,3,直至9,直到每组2个值已加在一起并存储在变量中。然后,我想用3个组,4个组,5个组,一直到10个组重复该过程。每个结果总数存储在一个单独的变量中。到目前为止,我能弄清楚如何做到这一点的唯一方法是: -
int i = 0;
int p = 1;
int q = 2;
int r = 3;
while (i < NumArray.Length - 3)
{
while (p < NumArray.Length - 2)
{
while (q < NumArray.Length-1)
{
while (r < NumArray.Length)
{
foursRet += NumArray[i] + NumArray[p] + NumArray[q]+ NumArray[r];
r++;
}
q++;
r = q + 1;
}
p++;
q = p + 1;
r = q + 1;
}
i++;
p = i + 1;
q = i + 2;
r = i + 3;
}
以上是4个组合的示例。 我想知道是否有人能够向我展示一种不那么冗长,更优雅的方式来实现我想要的东西。非常感谢。
答案 0 :(得分:4)
因为LINQ *的一切都更好:
using System; // Output is below
using System.Linq;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var inputArray = Enumerable.Range(0, 10).ToArray();
var grouped =
from Buckets in Enumerable.Range(1, inputArray.Length)
from IndexInBucket in Enumerable.Range(0, inputArray.Length / Buckets)
let StartPosInOriginalArray = IndexInBucket * Buckets
select new
{
BucketSize = Buckets,
BucketIndex = StartPosInOriginalArray,
Sum = inputArray.Skip(StartPosInOriginalArray).Take(Buckets).Sum()
};
foreach (var group in grouped)
{
Debug.Print(group.ToString());
}
Console.ReadKey();
}
}
} // SCROLL FOR OUTPUT
{ BucketSize = 1, BucketIndex = 0, Sum = 1 }
{ BucketSize = 1, BucketIndex = 1, Sum = 2 }
{ BucketSize = 1, BucketIndex = 2, Sum = 3 }
{ BucketSize = 1, BucketIndex = 3, Sum = 4 }
{ BucketSize = 1, BucketIndex = 4, Sum = 5 }
{ BucketSize = 1, BucketIndex = 5, Sum = 6 }
{ BucketSize = 1, BucketIndex = 6, Sum = 7 }
{ BucketSize = 1, BucketIndex = 7, Sum = 8 }
{ BucketSize = 1, BucketIndex = 8, Sum = 9 }
{ BucketSize = 1, BucketIndex = 9, Sum = 10 }
{ BucketSize = 2, BucketIndex = 0, Sum = 3 }
{ BucketSize = 2, BucketIndex = 2, Sum = 7 }
{ BucketSize = 2, BucketIndex = 4, Sum = 11 }
{ BucketSize = 2, BucketIndex = 6, Sum = 15 }
{ BucketSize = 2, BucketIndex = 8, Sum = 19 }
{ BucketSize = 3, BucketIndex = 0, Sum = 6 }
{ BucketSize = 3, BucketIndex = 3, Sum = 15 }
{ BucketSize = 3, BucketIndex = 6, Sum = 24 }
{ BucketSize = 4, BucketIndex = 0, Sum = 10 }
{ BucketSize = 4, BucketIndex = 4, Sum = 26 }
{ BucketSize = 5, BucketIndex = 0, Sum = 15 }
{ BucketSize = 5, BucketIndex = 5, Sum = 40 }
{ BucketSize = 6, BucketIndex = 0, Sum = 21 }
{ BucketSize = 7, BucketIndex = 0, Sum = 28 }
{ BucketSize = 8, BucketIndex = 0, Sum = 36 }
{ BucketSize = 9, BucketIndex = 0, Sum = 45 }
{ BucketSize = 10, BucketIndex = 0, Sum = 55 }
* LINQ
并非一切都好答案 1 :(得分:1)
如果我理解正确,你会得到一组长度为n
的数字。您想从中选择m
个数字的所有组合。然后,您想要对所有这些组合求和,最后计算这些总和的总和。
例如,给定n = 6
个数字,您可以用15种不同的方式选择m = 4
元素(数字是数字数组中的索引):
0 1 2 3 0 1 2 4 0 1 3 4 0 2 3 4 1 2 3 4 0 1 2 5 0 1 3 5 0 2 3 5 1 2 3 5 0 1 4 5 0 2 4 5 1 2 4 5 0 3 4 5 1 3 4 5 2 3 4 5
如果n < 32
(数组中不超过31个数字),您可以使用32位算术有效地生成索引。以下功能基于Gosper's hack:
IEnumerable<UInt32> GetIndexBits(Int32 m, Int32 n) {
unchecked {
var i = (UInt32) (1 << m) - 1;
var max = (UInt32) (1 << n);;
while (i < max) {
yield return i;
var u = (UInt32) (i & -i);
var v = u + i;
i = v + (((v ^ i)/u) >> 2);
}
}
}
使用m = 4
和n = 6
此函数将生成这些数字(以二进制形式显示):
001111 010111 011011 011101 011110 100111 101011 101101 101110 110011 110101 110110 111001 111010 111100
然后,您可以使用LINQ创建总和:
var m = 4;
var numbers = new[] { 1, 2, 3, 4, 5, 6 };
var sum = GetIndexBits(4, numbers.Length)
.Select(
bits => Enumerable
.Range(0, numbers.Length)
.Where(i => ((1 << i) & bits) != 0)
)
.Select(indices => indices.Sum(i => numbers[i]))
.Sum();
使用提供的输入,总和将为210,这与foursRet
包含数字1到6的问题中NumArray
的结果相同。