Click here to Skip to main content
Click here to Skip to main content

A C# List Permutation Iterator

By , 14 Nov 2009
 

Introduction

In this article, I will present a compact, easy to use method for iterating over all permutations of a given sequence. The iteration modifies the internal order of the sequence, visiting all permutations, and eventually restoring the original order (if the enumeration process is followed through).

Using the code

The implementation of the iterator is recursive; the recursion terminal condition is when the list has only one element, in which case, it is simply returned. In the recursive case, we iterate (n) times doing a recursive call to permutate the list's first (n-1) elements, and performing a rotate-right after each iteration.

Since each full enumeration eventually restores the sequence to its original order, the rotate-right is guaranteed to position a different element at the end of the sequence each time.

public static void RotateRight(IList sequence, int count)
{
    object tmp = sequence[count-1];
    sequence.RemoveAt(count - 1);
    sequence.Insert(0, tmp);
}

public static IEnumerable<IList> Permutate(IList sequence, int count)
{
    if (count == 1) yield return sequence;
    else
    {
        for (int i = 0; i < count; i++)
        {
            foreach (var perm in Permutate(sequence, count - 1))
                yield return perm;
            RotateRight(sequence, count);
        }
    }
}

Here is how we use this code to permutate a list of integers:

static void PermutateIntegersTest()
{
    List<int> seq = new List<int>() { 1, 2, 3, 4 };
    foreach (var permu in Permutate(seq, seq.Count))
    {
        foreach (var i in permu)
            Console.Write(i.ToString() + " ");
        Console.WriteLine();
    }
}

Or to permutate a string:

using System.Linq; // For the ToList() and ToArray() extension methods.

static void PermutateStringTest()
{
    string a = "word";
    foreach (List<char> perm in Permutate(a.ToCharArray().ToList(), a.Length))
    {
        string s = new string(perm.ToArray());
        Console.Write(s + "\t");
    }
    Console.WriteLine();
}

Remember that this implementation actually modifies the order of items in the sequence, and if that is not desired, a copy of the sequence must be made before the iteration is started.

That's it, enjoy.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Aviad P.
Software Developer (Senior)
Israel Israel
Member
Software developer since 1984, currently specializing in C# and .NET.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralPermutate() argumentsmemberSeth Morris21 Nov '09 - 23:02 
GeneralRecursionmemberPIEBALDconsult19 Nov '09 - 10:32 
GeneralRe: RecursionmemberAviad P.20 Nov '09 - 8:41 
GeneralRe: RecursionmemberGeorge I. Birbilis31 Oct '11 - 4:54 
GeneralRe: RecursionmemberGeorge I. Birbilis31 Oct '11 - 5:06 
GeneralSimilar to C++ STLmemberFredrik B17 Nov '09 - 3:01 
GeneralNeeds MoremvpJohn Simmons / outlaw programmer15 Nov '09 - 1:36 
How about providing use cases and sample output both using this code and NOT using this code for purposes of comparison?
 
.45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001

GeneralRe: Needs MorememberAviad P.15 Nov '09 - 2:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 15 Nov 2009
Article Copyright 2009 by Aviad P.
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid