2015-07-03 3 views
1

У меня есть следующий массив строк:Получить все возможные комбинации из списка строки

var words = new List<string> { "Win", "Care", "q10", "Mon", "Tue", "Wed", "Thur", "Fri", "Sat", "Sun" }; 

Я хочу, чтобы получить все комбинации из массива (используйте все слова в каждой комбинации)

например

  1. WinCareq10MonTueWedThurFriSatSun

  2. Monq10TueWedThurFriSatSunWinCare

  3. CareSunMonWinTueWedThurFriSatq10

  4. SunMonq10TueCareWedThurWinFriSat

ПРИМЕЧАНИЕ. В каждой комбинации должны использоваться все слова из списка строк.

+0

ОП ищете перестановки вместо комбинаций. –

+0

Вам нужны перестановки с повторами или без? – Vajura

+0

Мне нужны все слова из списка строк со всеми возможными позициями. Допускается повторение слов. – Gaurav123

ответ

0

Вы можете использовать это:

public static class EnumerableExtensions 
{ 
    public static IEnumerable<IEnumerable<T>> GetPermutations<T>(this IEnumerable<T> items) 
    { 
     foreach (var item in items) 
     { 
      var itemAsEnumerable = Enumerable.Repeat(item, 1); 
      var subSet = items.Except(itemAsEnumerable); 
      if (!subSet.Any()) 
      { 
       yield return itemAsEnumerable; 
      } 
      else 
      { 
       foreach (var sub in items.Except(itemAsEnumerable).GetPermutations()) 
       { 
        yield return itemAsEnumerable.Union(sub); 
       } 
      } 
     } 
    } 

Использование:

var list = new List<string> { "1", "2", "3" }; 
var permutations = list.GetPermutations(); 

var permutationsAsArray = permutations.Select(x => x.ToArray()).ToArray(); 
0

Во-первых, вы будете нуждаться в некоторых из методов переставлять массив целых чисел. F.E. вы можете попробовать следующее:

public static IEnumerable<int[]> Permutations(int start, int count) 
{ 
    if (count == 0) 
     yield break; 

    var array = Enumerable.Range(start, count) 
          .ToArray(); 

    if (count > 1) 
    { 
     do 
      yield return array; 
     while (NextPermutation(ref array)); 
    } 
    else 
     yield return array; 
} 

private static bool NextPermutation(ref int[] array) 
{ 
    int k = array.Length - 2; 
    while (k >= 0) 
    { 
     if (array[k] < array[k + 1]) 
      break; 

     k--; 
    } 

    if (k < 0) 
     return false; 

    int l = array.Length - 1; 
    while (l > k) 
    { 
     if (array[k] < array[l]) 
      break; 

     l--; 
    } 

    int tmp = array[k]; 
    array[k] = array[l]; 
    array[l] = tmp; 

    Array.Reverse(array, k + 1, array.Length - k - 1); 

    return true; 
} 

Этот метод выглядит сложным, но он является наиболее эффективным из существующих методов. Затем вы можете использовать перестановку целых чисел в качестве индексов:

IReadOnlyList<string> words = ... 
IEnumerable<int[]> permutations = Permutations(0, words.Length); 
foreach (var permutation in permutations) 
{ 
    var nextCase = new string[permutation.Length]; 
    for (int i = 0; i < permutation.Length; i++) 
     nextCase[i] = words[permutation[i]]; 

    var result = string.Join("", nextCase); 
    Console.WriteLine(result); 
} 
+0

Вам не нужна 'ref' часть' NextPermutation' – xanatos

+0

@xanatos Да, я дона Не нужно. Это просто, чтобы продемонстрировать, что параметр 'array' является изменяемым. –

Смежные вопросы