Y a t-il meilleur moyen plus court que de parcourir le tableau?
int[] arr = new int[] { 1, 2, 3 };
int sum = 0;
for (int i = 0; i < arr.Length; i++)
{
sum += arr[i];
}
clarification:
Un meilleur primaire signifie un code plus propre, mais des suggestions d'amélioration des performances sont également les bienvenues. (Comme déjà mentionné: division de grands tableaux).
Ce n'est pas comme si je cherchais à améliorer vos performances - je me demandais si ce type de sucre syntaxique n'était pas déjà disponible: "Il y a String.Join - qu'est-ce qui se passe avec int []?".
Si vous pouvez utiliser C # 3.5 et LINQ, essayez
int sum = arr.Sum();
Oui il y a. Avec .NET 3.5:
int sum = arr.Sum();
Console.WriteLine(sum);
Si vous n'utilisez pas .NET 3.5, vous pouvez procéder comme suit:
int sum = 0;
Array.ForEach(arr, delegate(int i) { sum += i; });
Console.WriteLine(sum);
Avec LINQ:
arr.Sum()
Cela dépend de la façon dont vous définissez mieux. Si vous voulez que le code paraisse plus propre, vous pouvez utiliser .Sum () comme indiqué dans d'autres réponses. Si vous souhaitez que l'opération s'exécute rapidement et que vous disposiez d'un grand tableau, vous pouvez le rendre parallèle en le décomposant en sous-sommes, puis en faisant la somme des résultats.
Si vous ne préférez pas LINQ, il est préférable d'utiliser la boucle foreach pour éviter les erreurs d'index.
int[] arr = new int[] { 1, 2, 3 };
int sum = 0;
foreach (var item in arr)
{
sum += item;
}
Pour les baies extrêmement volumineuses, il peut être avantageux d’effectuer le calcul en utilisant plusieurs processeurs/cœurs de la machine.
long sum = 0;
var options = new ParallelOptions()
{ MaxDegreeOfParallelism = Environment.ProcessorCount };
Parallel.ForEach(Partitioner.Create(0, arr.Length), options, range =>
{
long localSum = 0;
for (int i = range.Item1; i < range.Item2; i++)
{
localSum += arr[i];
}
Interlocked.Add(ref sum, localSum);
});
Un problème avec les solutions de boucle for ci-dessus est que pour le tableau d'entrée suivant avec toutes les valeurs positives, le résultat de la somme est négatif:
int[] arr = new int[] { Int32.MaxValue, 1 };
int sum = 0;
for (int i = 0; i < arr.Length; i++)
{
sum += arr[i];
}
Console.WriteLine(sum);
La somme est -2147483648, car le résultat positif est trop grand pour le type de données int et déborde dans une valeur négative.
Pour le même tableau d’entrée, les suggestions arr.Sum () provoquent la génération d’une exception de débordement.
Une solution plus robuste consiste à utiliser un type de données plus volumineux, tel qu'un "long" ou un "double" dans ce cas, pour la "somme" comme suit:
int[] arr = new int[] { Int32.MaxValue, 1 };
long sum = 0;
for (int i = 0; i < arr.Length; i++)
{
sum += arr[i];
}
Pour les versions beaucoup plus rapides qui implémentent le parallèle de données (SIMD/SSE) et le multi-core, vous pouvez utiliser le package nuget HPCsharp ( https://www.nuget.org/packages/HPCsharp/ ), qui est open source et libre. Ces implémentations sont bien plus rapides que les arrêts Linq arr.Sum () et arr.AsParallel.Sum () et ne génèrent pas d'exception de débordement ni de débordement dans les négatifs.
HPCsharp implémente également un arr.Sum () plus précis pour les tableaux flottants et doubles, en utilisant les algorithmes de sommation à virgule flottante de Kahan et Neumaier.
L'utilisation de foreach serait un code plus court, mais vous ferez probablement exactement les mêmes étapes au moment de l'exécution, une fois que l'optimisation JIT reconnaît la comparaison à Length dans l'expression de contrôle for-loop.
Dans l'une de mes applications, j'ai utilisé:
public class ClassBlock
{
public int[] p;
public int Sum
{
get { int s = 0; Array.ForEach(p, delegate (int i) { s += i; }); return s; }
}
}
Une alternative consiste également à utiliser la méthode d'extension Aggregate()
.
var sum = arr.Aggregate((temp, x) => temp+x);