1

I have the following array of strings:

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

I want to get all combinations from the array (use all words in each combination)

e.g.

  1. WinCareq10MonTueWedThurFriSatSun

  2. Monq10TueWedThurFriSatSunWinCare

  3. CareSunMonWinTueWedThurFriSatq10

  4. SunMonq10TueCareWedThurWinFriSat

NOTE : In every combination, all words from list of string must be used.

Chris Mantle
  • 6,595
  • 3
  • 34
  • 48
Gaurav123
  • 5,059
  • 6
  • 51
  • 81
  • 1
    The OP is looking for permutations instead of combinations. – Jaanus Varus Jul 03 '15 at 07:42
  • do you need permutations with repeats or without? – Vajura Jul 03 '15 at 07:43
  • I want all words from list of string with all possible positions. Repetition of words is allowed. – Gaurav123 Jul 03 '15 at 07:46
  • 4
    Why does everybody ask WHY he want to do something instead of get him an answer? – Sebastian Schumann Jul 03 '15 at 08:09
  • 1
    @PaulZahra It was more a general problem of SO. Xanatos and David Arno aked - but WHY? Someone has a problem and is looking for a solution. There is no need to ask why when a solution is available. Only if no solution exists one should ask why. That's my opinion but this question is not the place to discuss it. – Sebastian Schumann Jul 03 '15 at 08:17
  • @Verarind While I understand how some might be frustrated by that kind of interaction... sometimes I find myself wondering if the 'asker' completely understands the problem at hand and whether a different solution would be 'better'... so sometimes asking 'WHY?' is pretty valid. – Paul Zahra Jul 03 '15 at 08:20
  • @Verarind, I often ask why because I think it a constructive thing to do at times. Here I asked it because I can't see the point to doing what the OP wants to do. The answer might then educate me. Other times, I want to check whether the OP is asking the "wrong" question. As explained by Paul, I might then be able to offer a far better answer a more general problem and teach better programming techniques along the way. – David Arno Jul 03 '15 at 08:54
  • Try using http://stackoverflow.com/questions/756055/listing-all-permutations-of-a-string-integer – Kiquenet Sep 18 '15 at 09:35

2 Answers2

1

You can use this:

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

Usage:

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

var permutationsAsArray = permutations.Select(x => x.ToArray()).ToArray();
Sebastian Schumann
  • 3,204
  • 19
  • 37
1

First, you'll need some of methods to permute an array of integers. F.e. you can try this:

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

This method looks complicated, but it's most efficient of existing methods. Then you'll can use permutated integers as indices:

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);
}
Mark Shevchenko
  • 7,937
  • 1
  • 25
  • 29