2013-03-01 10 views
8

Chciałbym być w stanie podjąć listę jak tenWszystkie permutacje listy

var list=new List<int>{0, 1, 2}; 

I uzyskać wynik jak ten

var result= 
    new List<List<int>>{ 
     new List<int>{0, 1, 2}, 
     new List<int>{0, 2, 1}, 
     new List<int>{1, 0, 2}, 
     new List<int>{1, 2, 0}, 
     new List<int>{2, 0, 1}, 
     new List<int>{2, 1, 0} 
    }; 

Nie jestem zainteresowany w zestawach z brakującymi liczby, po prostu kombinacje istniejących liczb. Jakieś pomysły?


Ponadto już sprawdziłem rozwiązania takie jak Getting all possible combinations from a list of numbers i nie pasują one.

To jedna daje mi coś takiego

var result= 
    new List<List<int>> { 
     // [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]] 
     // serialized the result to JSON so it would be quicker. 
    }; 

I nie wypluć wszystkich kombinacjach.


+6

Co szukasz jest tym _Permutations_ z listy. Zostało to zadane wiele razy tutaj wcześniej :) Oto bardzo podobne pytanie: http://stackoverflow.com/questions/3319586/getting-all-possible-permutations-from-a-list-of-numbers –

+2

Ten wynik doesn obejmuje wszystkie elementy i zawiera permutacje wykluczające elementy. Próbowałem ich obu i nie pasowali. Nie udało mi się znaleźć żadnego działającego przykładu, który nie działa tak jak ten, z którym się łączyłeś. –

+0

W jaki sposób obsługiwane są duplikaty? Co jeśli otrzymałeś "0, 1, 1, 1, 2, 2"? – yoozer8

Odpowiedz

7

Spróbuj metody rozszerzenie na rozmiar:

public static IEnumerable<IEnumerable<T>> Permute<T>(this IEnumerable<T> sequence) 
{ 
    if (sequence == null) 
    { 
     yield break; 
    } 

    var list = sequence.ToList(); 

    if (!list.Any()) 
    { 
     yield return Enumerable.Empty<T>(); 
    } 
    else 
    { 
     var startingElementIndex = 0; 

     foreach (var startingElement in list) 
     { 
      var remainingItems = list.AllExcept(startingElementIndex); 

      foreach (var permutationOfRemainder in remainingItems.Permute()) 
      { 
       yield return startingElement.Concat(permutationOfRemainder); 
      } 

      startingElementIndex++; 
     } 
    } 
} 

private static IEnumerable<T> Concat<T>(this T firstElement, IEnumerable<T> secondSequence) 
{ 
    yield return firstElement; 
    if (secondSequence == null) 
    { 
     yield break; 
    } 

    foreach (var item in secondSequence) 
    { 
     yield return item; 
    } 
} 

private static IEnumerable<T> AllExcept<T>(this IEnumerable<T> sequence, int indexToSkip) 
{ 
    if (sequence == null) 
    { 
     yield break; 
    } 

    var index = 0; 

    foreach (var item in sequence.Where(item => index++ != indexToSkip)) 
    { 
     yield return item; 
    } 
} 
+2

Tak, myślę, że wygrasz. –

Powiązane problemy