2012-01-12 45 views
5

Tengo una matriz de enteros de diez elementos. Quiero sumar los elementos por grupo, así que, por ejemplo, quiero agregar el valor en el elemento 0 con el valor en el elemento 1, luego con el valor en el elemento 2, luego en el 3, y así sucesivamente hasta el elemento 9, luego sumar el valor en el elemento 1 con el valor de 2,3, hasta 9 hasta que cada grupo de 2 valores se haya agregado y se haya almacenado en una variable. Luego quiero repetir el proceso con grupos de 3, grupos de 4, de 5, hasta el grupo de 10. Cada total resultante se almacena en una variable separada. Hasta ahora, la única manera que puedo encontrar la manera de hacerlo es por lo tanto: -Agregar elementos de una matriz

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

Lo anterior es un ejemplo de sumar grupos de 4. Me preguntaba si alguien podría ser tan amable de mostrar un menor forma prolija y más elegante de lograr lo que quiero. Muchas gracias.

+1

¿Huele a tarea? Si es así, por favor marque como tal. Si no, ¿te importaría explicarlo? –

+0

Estoy un poco confundido en cuanto a los requisitos. Puede actualizar la pregunta con una entrada de ejemplo y la salida requerida. – Jamiec

+0

¿Puede explicar el propósito de esos cálculos, porque tal vez haya un mejor enfoque para la solución ... – ChrFin

Respuesta

4

Porque todo es mejor con 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 } 

* No todo es mejor con LINQ

+1

incluso podrías hacerlo mejor: 'Enumerable.Range (0, 10) .ToArray()' :) –

+0

¡Buena captura, no puedo creer que no haya hecho eso! –

1

Si he entendido bien tiene una matriz de números con una longitud de n. Desea elegir todas las combinaciones de m números de esto. Luego desea sumar todas estas combinaciones y finalmente calcular la suma de estas sumas.

Por ejemplo dados n = 6 números que puede recoger m = 4 elementos en 15 formas diferentes (los números son índices de la matriz de números):

 
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 

If n < 32 (no más de 31 números en la matriz) se puede generar de manera eficiente los índices usando aritmética de 32 bits. La siguiente función se basa en 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); 
    } 
    } 
} 

Con m = 4 y n = 6 esta función generará estos números (representada en forma binaria):

 
001111 
010111 
011011 
011101 
011110 
100111 
101011 
101101 
101110 
110011 
110101 
110110 
111001 
111010 
111100 

continuación, puede crear la suma usando 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(); 

Con la entrada proporcionada, la suma será 210, que es el mismo resultado que foursRet en th e pregunta cuando NumArray contiene los números 1 a 6.

Cuestiones relacionadas