48 votes

Toutes les combinaisons possibles d'une liste de valeurs

J'ai une liste d'entiers List<int> dans mon programme C#. Cependant, je ne connais le nombre d'éléments que j'ai dans ma liste qu'au moment de l'exécution.

Disons, par souci de simplicité, ma liste est {1, 2, 3} Maintenant, je dois générer toutes les combinaisons possibles comme suit.

 {1, 2, 3}
{1, 2}
{1, 3}
{2, 3}
{1}
{2}
{3}

Quelqu'un peut-il s'il vous plaît aider avec cela?

79voto

ojlovecd Points 2442

essaye ça:

 static void Main(string[] args)
{

    GetCombination(new List<int> { 1, 2, 3 });
}

static void GetCombination(List<int> list)
{
    double count = Math.Pow(2, list.Count);
    for (int i = 1; i <= count - 1; i++)
    {
        string str = Convert.ToString(i, 2).PadLeft(list.Count, '0');
        for (int j = 0; j < str.Length; j++)
        {
            if (str[j] == '1')
            {
                Console.Write(list[j]);
            }
        }
        Console.WriteLine();
    }
}

26voto

jaolho Points 21

Voici deux solutions génériques pour les listes fortement typées qui renverront toutes les combinaisons uniques de membres de la liste (si vous pouvez résoudre ce problème avec un code plus simple, je vous salue) :

 // Recursive
public static List<List<T>> GetAllCombos<T>(List<T> list)
{
  List<List<T>> result = new List<List<T>>();
  // head
  result.Add(new List<T>());
  result.Last().Add(list[0]);
  if (list.Count == 1)
    return result;
  // tail
  List<List<T>> tailCombos = GetAllCombos(list.Skip(1).ToList());
  tailCombos.ForEach(combo =>
  {
    result.Add(new List<T>(combo));
    combo.Add(list[0]);
    result.Add(new List<T>(combo));
  });
  return result;
}

// Iterative, using 'i' as bitmask to choose each combo members
public static List<List<T>> GetAllCombos<T>(List<T> list)
{
  int comboCount = (int) Math.Pow(2, list.Count) - 1;
  List<List<T>> result = new List<List<T>>();
  for (int i = 1; i < comboCount + 1; i++)
  {
    // make each combo here
    result.Add(new List<T>());
    for (int j = 0; j < list.Count; j++)
    {
      if ((i >> j) % 2 != 0)
        result.Last().Add(list[j]);
    }
  }
  return result;
}

// Example usage
List<List<int>> combos = GetAllCombos(new int[] { 1, 2, 3 }.ToList());

19voto

Dmitry Bychenko Points 17719

En supposant que tous les éléments de la collection initail soient distincts , nous pouvons essayer d'utiliser Linq pour interroger ; généralisons la solution :

Code:

 public static IEnumerable<T[]> Combinations<T>(IEnumerable<T> source) {
  if (null == source)
    throw new ArgumentNullException(nameof(source));

  T[] data = source.ToArray();

  return Enumerable
    .Range(0, 1 << (data.Length))
    .Select(index => data
       .Where((v, i) => (index & (1 << i)) != 0)
       .ToArray());
}

Démo :

   var data = new char[] { 'A', 'B', 'C' };

  var result = Combinations(data);

  foreach (var item in result)
    Console.WriteLine($"[{string.Join(", ", item)}]);

Résultat:

 []
[A]
[B]
[A, B]
[C]
[A, C]
[B, C]
[A, B, C]

Si vous souhaitez exclure le tableau vide initial, mettez .Range(1, (1 << (data.Length)) - 1) au lieu de .Range(0, 1 << (data.Length))

9voto

Sindorej Points 136

Voici une solution générique utilisant la récursivité

 public static ICollection<ICollection<T>> Permutations<T>(ICollection<T> list) {
    var result = new List<ICollection<T>>();
    if (list.Count == 1) { // If only one possible permutation
        result.Add(list); // Add it and return it
        return result;
    }
    foreach (var element in list) { // For each element in that list
        var remainingList = new List<T>(list);
        remainingList.Remove(element); // Get a list containing everything except of chosen element
        foreach (var permutation in Permutations<T>(remainingList)) { // Get all possible sub-permutations
            permutation.Add(element); // Add that element
            result.Add(permutation);
        }
    }
    return result;
}

Je sais que c'est un vieux post, mais quelqu'un pourrait trouver cela utile.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X