198

A common task in programming interviews (not from my experience of interviews though) is to take a string or an integer and list every possible permutation.

Is there an example of how this is done and the logic behind solving such a problem?

I've seen a few code snippets but they weren't well commented/explained and thus hard to follow.

1

30 Answers 30

185

First of all: it smells like recursion of course!

Since you also wanted to know the principle, I did my best to explain it human language. I think recursion is very easy most of the times. You only have to grasp two steps:

  1. The first step
  2. All the other steps (all with the same logic)

In human language:

In short:

  1. The permutation of 1 element is one element.
  2. The permutation of a set of elements is a list each of the elements, concatenated with every permutation of the other elements.

Example:

If the set just has one element -->
return it.
perm(a) -> a

If the set has two characters: for each element in it: return the element, with the permutation of the rest of the elements added, like so:

perm(ab) ->

a + perm(b) -> ab

b + perm(a) -> ba

Further: for each character in the set: return a character, concatenated with a permutation of > the rest of the set

perm(abc) ->

a + perm(bc) --> abc, acb

b + perm(ac) --> bac, bca

c + perm(ab) --> cab, cba

perm(abc...z) -->

a + perm(...), b + perm(....)
....

I found the pseudocode on http://www.programmersheaven.com/mb/Algorithms/369713/369713/permutation-algorithm-help/:

makePermutations(permutation) { if (length permutation < required length) { for (i = min digit to max digit) { if (i not in permutation) { makePermutations(permutation+i) } } } else { add permutation to list } } 

C#

OK, and something more elaborate (and since it is tagged c #), from http://radio.weblogs.com/0111551/stories/2002/10/14/permutations.html : Rather lengthy, but I decided to copy it anyway, so the post is not dependent on the original.

The function takes a string of characters, and writes down every possible permutation of that exact string, so for example, if "ABC" has been supplied, should spill out:

ABC, ACB, BAC, BCA, CAB, CBA.

Code:

class Program { private static void Swap(ref char a, ref char b) { if (a == b) return; var temp = a; a = b; b = temp; } public static void GetPer(char[] list) { int x = list.Length - 1; GetPer(list, 0, x); } private static void GetPer(char[] list, int k, int m) { if (k == m) { Console.Write(list); } else for (int i = k; i <= m; i++) { Swap(ref list[k], ref list[i]); GetPer(list, k + 1, m); Swap(ref list[k], ref list[i]); } } static void Main() { string str = "sagiv"; char[] arr = str.ToCharArray(); GetPer(arr); } } 
Sign up to request clarification or add additional context in comments.

7 Comments

For a bit more clarity, I would call k "recursionDepth" and call m "maxDepth".
The 2nd swap (Swap(ref list[k], ref list[i]);) is unncessary.
Thank you for this solution. I created this fiddle (dotnetfiddle.net/oTzihw) from it (with proper naming instead of k and m). As far as I understand the algo, the second Swap is required (to backtrack) since you edit the original array in-place.
a minor point: It looks like the Swap method is better to be implemented with a temporary buffer variable and not using XORs (dotnetperls.com/swap)
Using C# 7 tuples you can make the swap a lot more elegant: (a[x], a[y]) = (a[y], a[x]);
|
104

It's just two lines of code if LINQ is allowed to use. Please see my answer here.

EDIT

Here is my generic function which can return all the permutations (not combinations) from a list of T:

static IEnumerable<IEnumerable<T>> GetPermutations<T>(IEnumerable<T> list, int length) { if (length == 1) return list.Select(t => new T[] { t }); return GetPermutations(list, length - 1) .SelectMany(t => list.Where(e => !t.Contains(e)), (t1, t2) => t1.Concat(new T[] { t2 })); } 

Example:

IEnumerable<IEnumerable<int>> result = GetPermutations(Enumerable.Range(1, 3), 3); 

Output - a list of integer-lists:

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

As this function uses LINQ so it requires .net 3.5 or higher.

10 Comments

combinations and permutations are different things. it's similar, but your answer there seems to be answering a different problem than all the permutations of a set of elements.
@ShawnKovac, thanks for pointing this out! I've updated my code from combination to permutation.
@Pengyang I looked at your other answer and I will say that this helped me a great deal but I have another situation that I don't know if you pointed out the correct way of solving it. I wanted to find all permutations of a word like 'HALLOWEEN' but found that I also want to include both 'L's and both 'E's in the result set. In my iterations I loop over your method giving increased length with each iteration(length++) and would expect that given the full length of the word HALLOWEEN (9 chars) I would get results 9 chars long... but this is not the case: I only get 7 (1 L and 1 E are omitted)
@MegaMark This function requires the elements to be unique. Try this: const string s = "HALLOWEEN"; var result = GetPermutations(Enumerable.Range(0, s.Length), s.Length).Select(t => t.Select(i => s[i]));
While I am a fan of LINQ myself, I'm afraid this solution has a horrible performance. This may be caused by lazy evaluation or all the iterator overhead, I don't know, but I did a few time measures comparing this solution to Yurik's implementation and his one was around factor 40 faster.
|
47

Here I have found the solution. It was written in Java, but I have converted it to C#. I hope it will help you.

Enter image description here

Here's the code in C#:

static void Main(string[] args) { string str = "ABC"; char[] charArry = str.ToCharArray(); Permute(charArry, 0, 2); Console.ReadKey(); } static void Permute(char[] arry, int i, int n) { int j; if (i==n) Console.WriteLine(arry); else { for(j = i; j <=n; j++) { Swap(ref arry[i],ref arry[j]); Permute(arry,i+1,n); Swap(ref arry[i], ref arry[j]); //backtrack } } } static void Swap(ref char a, ref char b) { char tmp; tmp = a; a=b; b = tmp; } 

2 Comments

Is it ported from another language? Definitely +1 for the image, because it really adds value. However, the code itself seems to have a certain improvement potential. Some minor parts aren't needed but most importantly, I'm getting this C++ feeling when we send in something and do stuff to it instead of providing in-parameters and fetching a returned value. In fact, I used your image to implement a C#-styled C# code (style being my personal perception, of course), and it aided me greatly, so when I'll post it I'll definitely steal it from you (and credit you for it).
C# supports swapping like Python since its introduction of tuples.
23

Recursion is not necessary, here is good information about this solution.

var values1 = new[] { 1, 2, 3, 4, 5 }; foreach (var permutation in values1.GetPermutations()) { Console.WriteLine(string.Join(", ", permutation)); } var values2 = new[] { 'a', 'b', 'c', 'd', 'e' }; foreach (var permutation in values2.GetPermutations()) { Console.WriteLine(string.Join(", ", permutation)); } Console.ReadLine(); 

I have been used this algorithm for years, it has O(N) time and space complexity to calculate each permutation.

public static class SomeExtensions { public static IEnumerable<IEnumerable<T>> GetPermutations<T>(this IEnumerable<T> enumerable) { var array = enumerable as T[] ?? enumerable.ToArray(); var factorials = Enumerable.Range(0, array.Length + 1) .Select(Factorial) .ToArray(); for (var i = 0L; i < factorials[array.Length]; i++) { var sequence = GenerateSequence(i, array.Length - 1, factorials); yield return GeneratePermutation(array, sequence); } } private static IEnumerable<T> GeneratePermutation<T>(T[] array, IReadOnlyList<int> sequence) { var clone = (T[]) array.Clone(); for (int i = 0; i < clone.Length - 1; i++) { Swap(ref clone[i], ref clone[i + sequence[i]]); } return clone; } private static int[] GenerateSequence(long number, int size, IReadOnlyList<long> factorials) { var sequence = new int[size]; for (var j = 0; j < sequence.Length; j++) { var facto = factorials[sequence.Length - j]; sequence[j] = (int)(number / facto); number = (int)(number % facto); } return sequence; } static void Swap<T>(ref T a, ref T b) { T temp = a; a = b; b = temp; } private static long Factorial(int n) { long result = n; for (int i = 1; i < n; i++) { result = result * i; } return result; } } 

3 Comments

Works out of the box!
maybe I don't understand O(n) notation. doesn't the N refer to how many "inner loops" are necessary to make your algorithm work? seems to me like if you have N numbers, it seems like it's O(N * N!) (because N! times it has to do N swaps). Plus, it has to do a ton of array copying. This code is "neat", but I wouldn't use it.
@ericfrazer Each permutation only uses one array copy, and O(N-1) for the sequence and O(N) for the swaps, which is O(N). And I'm still using this in production but with a refactor to generate only one permutation like: GetPermutation(i) where 0 <= i <= N!-1. I will be happy to use something with better performance than this, so be free to call a reference for something better, the most of the alternatives uses O(N!) in memory so you might check that too.
17
class Program { public static void Main(string[] args) { Permutation("abc"); } static void Permutation(string rest, string prefix = "") { if (string.IsNullOrEmpty(rest)) Console.WriteLine(prefix); // Each letter has a chance to be permutated for (int i = 0; i < rest.Length; i++) { Permutation(rest.Remove(i, 1), prefix + rest[i]); } } } 

Comments

14

Slightly modified version in C# that yields needed permutations in an array of ANY type.

 // USAGE: create an array of any type, and call Permutations() var vals = new[] {"a", "bb", "ccc"}; foreach (var v in Permutations(vals)) Console.WriteLine(string.Join(",", v)); // Print values separated by comma public static IEnumerable<T[]> Permutations<T>(T[] values, int fromInd = 0) { if (fromInd + 1 == values.Length) yield return values; else { foreach (var v in Permutations(values, fromInd + 1)) yield return v; for (var i = fromInd + 1; i < values.Length; i++) { SwapValues(values, fromInd, i); foreach (var v in Permutations(values, fromInd + 1)) yield return v; SwapValues(values, fromInd, i); } } } private static void SwapValues<T>(T[] values, int pos1, int pos2) { if (pos1 != pos2) { T tmp = values[pos1]; values[pos1] = values[pos2]; values[pos2] = tmp; } } 

2 Comments

One slight caveat with this implementation: it only works properly if you don't attempt to store the enumeration value. If you try to do something like Permutations(vals).ToArray() then you end up with N references to the same array. If you want to be able to store the results you have to manually create a copy. E.g. Permutations(values).Select(v => (T[])v.Clone())
I have tested this approach on very big permutations (tens of millions). It does require a very careful use. It totally outperforms other solutions in both speed and memory usage.
9

I liked FBryant87 approach since it's simple. Unfortunately, it does like many other "solutions" not offer all permutations or of e.g. an integer if it contains the same digit more than once. Take 656123 as an example. The line:

var tail = chars.Except(new List<char>(){c}); 

using Except will cause all occurrences to be removed, i.e. when c = 6, two digits are removed and we are left with e.g. 5123. Since none of the solutions I tried solved this, I decided to try and solve it myself by FBryant87's code as base. This is what I came up with:

private static List<string> FindPermutations(string set) { var output = new List<string>(); if (set.Length == 1) { output.Add(set); } else { foreach (var c in set) { // Remove one occurrence of the char (not all) var tail = set.Remove(set.IndexOf(c), 1); foreach (var tailPerms in FindPermutations(tail)) { output.Add(c + tailPerms); } } } return output; } 

I simply just remove the first found occurrence using .Remove and .IndexOf. Seems to work as intended for my usage at least. I'm sure it could be made cleverer.

One thing to note though: The resulting list may contain duplicates, so make sure you either make the method return e.g. a HashSet instead or remove the duplicates after the return using any method you like.

1 Comment

Works like an absolute beauty, first I've found that handles duplicate characters +1
8

First of all, sets have permutations, not strings or integers, so I'll just assume you mean "the set of characters in a string."

Note that a set of size n has n! n-permutations.

The following pseudocode (from Wikipedia), called with k = 1...n! will give all the permutations:

function permutation(k, s) { for j = 2 to length(s) { swap s[(k mod j) + 1] with s[j]; // note that our array is indexed starting at 1 k := k / j; // integer division cuts off the remainder } return s; } 

Here's the equivalent Python code (for 0-based array indexes):

def permutation(k, s): r = s[:] for j in range(2, len(s)+1): r[j-1], r[k%j] = r[k%j], r[j-1] k = k/j+1 return r 

1 Comment

what language is this? the question is marked C#. i don't know what k := k / j; does.
6

Here is a simple solution in c# using recursion,

void Main() { string word = "abc"; WordPermuatation("",word); } void WordPermuatation(string prefix, string word) { int n = word.Length; if (n == 0) { Console.WriteLine(prefix); } else { for (int i = 0; i < n; i++) { WordPermuatation(prefix + word[i],word.Substring(0, i) + word.Substring(i + 1, n - (i+1))); } } } 

Comments

5

Here's a purely functional F# implementation:

  let factorial i = let rec fact n x = match n with | 0 -> 1 | 1 -> x | _ -> fact (n-1) (x*n) fact i 1 let swap (arr:'a array) i j = [| for k in 0..(arr.Length-1) -> if k = i then arr.[j] elif k = j then arr.[i] else arr.[k] |] let rec permutation (k:int,j:int) (r:'a array) = if j = (r.Length + 1) then r else permutation (k/j+1, j+1) (swap r (j-1) (k%j)) let permutations (source:'a array) = seq { for k = 0 to (source |> Array.length |> factorial) - 1 do yield permutation (k,2) source } 

Performance can be greatly improved by changing swap to take advantage of the mutable nature of CLR arrays, but this implementation is thread safe with regards to the source array and that may be desirable in some contexts. Also, for arrays with more than 16 elements int must be replaced with types with greater/arbitrary precision as factorial 17 results in an int32 overflow.

Comments

5

Here is an easy to understand permutaion function for both string and integer as input. With this you can even set your output length(which in normal case it is equal to input length)

String

 static ICollection<string> result; public static ICollection<string> GetAllPermutations(string str, int outputLength) { result = new List<string>(); MakePermutations(str.ToCharArray(), string.Empty, outputLength); return result; } private static void MakePermutations( char[] possibleArray,//all chars extracted from input string permutation, int outputLength//the length of output) { if (permutation.Length < outputLength) { for (int i = 0; i < possibleArray.Length; i++) { var tempList = possibleArray.ToList<char>(); tempList.RemoveAt(i); MakePermutations(tempList.ToArray(), string.Concat(permutation, possibleArray[i]), outputLength); } } else if (!result.Contains(permutation)) result.Add(permutation); } 

and for Integer just change the caller method and MakePermutations() remains untouched:

 public static ICollection<int> GetAllPermutations(int input, int outputLength) { result = new List<string>(); MakePermutations(input.ToString().ToCharArray(), string.Empty, outputLength); return result.Select(m => int.Parse(m)).ToList<int>(); } 

example 1: GetAllPermutations("abc",3); "abc" "acb" "bac" "bca" "cab" "cba"

example 2: GetAllPermutations("abcd",2); "ab" "ac" "ad" "ba" "bc" "bd" "ca" "cb" "cd" "da" "db" "dc"

example 3: GetAllPermutations(486,2); 48 46 84 86 64 68

1 Comment

I like your solution because this is easy to understand, thank you for that! Yet I chose to go with that one: stackoverflow.com/questions/756055/…. The reason being that ToList, ToArray and RemoveAt all have a time complexity of O(N). So basically you have to go over all the elements of the collection (see stackoverflow.com/a/15042066/1132522). Same for the int where you basically go over all the elements again at the end to convert them to int. I agree that this doesn't have much impact for "abc" or 486 though.
4

Building on @Peter's solution, here's a version that declares a simple LINQ-style Permutations() extension method that works on any IEnumerable<T>.

Usage (on string characters example):

foreach (var permutation in "abc".Permutations()) { Console.WriteLine(string.Join(", ", permutation)); } 

Outputs:

a, b, c a, c, b b, a, c b, c, a c, b, a c, a, b 

Or on any other collection type:

foreach (var permutation in (new[] { "Apples", "Oranges", "Pears"}).Permutations()) { Console.WriteLine(string.Join(", ", permutation)); } 

Outputs:

Apples, Oranges, Pears Apples, Pears, Oranges Oranges, Apples, Pears Oranges, Pears, Apples Pears, Oranges, Apples Pears, Apples, Oranges 
using System; using System.Collections.Generic; using System.Linq; public static class PermutationExtension { public static IEnumerable<T[]> Permutations<T>(this IEnumerable<T> source) { var sourceArray = source.ToArray(); var results = new List<T[]>(); Permute(sourceArray, 0, sourceArray.Length - 1, results); return results; } private static void Swap<T>(ref T a, ref T b) { T tmp = a; a = b; b = tmp; } private static void Permute<T>(T[] elements, int recursionDepth, int maxDepth, ICollection<T[]> results) { if (recursionDepth == maxDepth) { results.Add(elements.ToArray()); return; } for (var i = recursionDepth; i <= maxDepth; i++) { Swap(ref elements[recursionDepth], ref elements[i]); Permute(elements, recursionDepth + 1, maxDepth, results); Swap(ref elements[recursionDepth], ref elements[i]); } } } 

Comments

2

Here is the function which will print all permutaion. This function implements logic Explained by peter.

public class Permutation { //http://www.java2s.com/Tutorial/Java/0100__Class-Definition/RecursivemethodtofindallpermutationsofaString.htm public static void permuteString(String beginningString, String endingString) { if (endingString.Length <= 1) Console.WriteLine(beginningString + endingString); else for (int i = 0; i < endingString.Length; i++) { String newString = endingString.Substring(0, i) + endingString.Substring(i + 1); permuteString(beginningString + endingString.ElementAt(i), newString); } } } static void Main(string[] args) { Permutation.permuteString(String.Empty, "abc"); Console.ReadLine(); } 

Comments

2

Here's a high level example I wrote which illustrates the human language explanation Peter gave:

 public List<string> FindPermutations(string input) { if (input.Length == 1) return new List<string> { input }; var perms = new List<string>(); foreach (var c in input) { var others = input.Remove(input.IndexOf(c), 1); perms.AddRange(FindPermutations(others).Select(perm => c + perm)); } return perms; } 

2 Comments

This solution is actually flawed in that if the string set contains any repeat characters, it will fail. For example, on the word 'test', the Except command will remove both instances of 't' instead of just the first and last when necessary.
@Middas well spotted, fortunately hug has come up with a solution to address this.
2

Base/Revise on Pengyang answer

And inspired from permutations-in-javascript

The c# version FunctionalPermutations should be this

static IEnumerable<IEnumerable<T>> FunctionalPermutations<T>(IEnumerable<T> elements, int length) { if (length < 2) return elements.Select(t => new T[] { t }); /* Pengyang answser.. return _recur_(list, length - 1).SelectMany(t => list.Where(e => !t.Contains(e)),(t1, t2) => t1.Concat(new T[] { t2 })); */ return elements.SelectMany((element_i, i) => FunctionalPermutations(elements.Take(i).Concat(elements.Skip(i + 1)), length - 1) .Select(sub_ei => new[] { element_i }.Concat(sub_ei))); } 

Comments

2

Here's my implementation of permutation. Don't mind the variable names, as I was doing it for fun :)

class combinations { static void Main() { string choice = "y"; do { try { Console.WriteLine("Enter word :"); string abc = Console.ReadLine().ToString(); Console.WriteLine("Combinatins for word :"); List<string> final = comb(abc); int count = 1; foreach (string s in final) { Console.WriteLine("{0} --> {1}", count++, s); } Console.WriteLine("Do you wish to continue(y/n)?"); choice = Console.ReadLine().ToString(); } catch (Exception exc) { Console.WriteLine(exc); } } while (choice == "y" || choice == "Y"); } static string swap(string test) { return swap(0, 1, test); } static List<string> comb(string test) { List<string> sec = new List<string>(); List<string> first = new List<string>(); if (test.Length == 1) first.Add(test); else if (test.Length == 2) { first.Add(test); first.Add(swap(test)); } else if (test.Length > 2) { sec = generateWords(test); foreach (string s in sec) { string init = s.Substring(0, 1); string restOfbody = s.Substring(1, s.Length - 1); List<string> third = comb(restOfbody); foreach (string s1 in third) { if (!first.Contains(init + s1)) first.Add(init + s1); } } } return first; } static string ShiftBack(string abc) { char[] arr = abc.ToCharArray(); char temp = arr[0]; string wrd = string.Empty; for (int i = 1; i < arr.Length; i++) { wrd += arr[i]; } wrd += temp; return wrd; } static List<string> generateWords(string test) { List<string> final = new List<string>(); if (test.Length == 1) final.Add(test); else { final.Add(test); string holdString = test; while (final.Count < test.Length) { holdString = ShiftBack(holdString); final.Add(holdString); } } return final; } static string swap(int currentPosition, int targetPosition, string temp) { char[] arr = temp.ToCharArray(); char t = arr[currentPosition]; arr[currentPosition] = arr[targetPosition]; arr[targetPosition] = t; string word = string.Empty; for (int i = 0; i < arr.Length; i++) { word += arr[i]; } return word; } } 

Comments

1

This is my solution which it is easy for me to understand

class ClassicPermutationProblem { ClassicPermutationProblem() { } private static void PopulatePosition<T>(List<List<T>> finalList, List<T> list, List<T> temp, int position) { foreach (T element in list) { List<T> currentTemp = temp.ToList(); if (!currentTemp.Contains(element)) currentTemp.Add(element); else continue; if (position == list.Count) finalList.Add(currentTemp); else PopulatePosition(finalList, list, currentTemp, position + 1); } } public static List<List<int>> GetPermutations(List<int> list) { List<List<int>> results = new List<List<int>>(); PopulatePosition(results, list, new List<int>(), 1); return results; } } static void Main(string[] args) { List<List<int>> results = ClassicPermutationProblem.GetPermutations(new List<int>() { 1, 2, 3 }); } 

Comments

1

If performance and memory is an issue, I suggest this very efficient implementation. According to Heap's algorithm in Wikipedia, it should be the fastest. Hope it will fits your need :-) !

Just as comparison of this with a Linq implementation for 10! (code included):

  • This: 36288000 items in 235 millisecs
  • Linq: 36288000 items in 50051 millisecs

    using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.CompilerServices; using System.Text; namespace WpfPermutations { /// <summary> /// EO: 2016-04-14 /// Generator of all permutations of an array of anything. /// Base on Heap's Algorithm. See: https://en.wikipedia.org/wiki/Heap%27s_algorithm#cite_note-3 /// </summary> public static class Permutations { /// <summary> /// Heap's algorithm to find all pmermutations. Non recursive, more efficient. /// </summary> /// <param name="items">Items to permute in each possible ways</param> /// <param name="funcExecuteAndTellIfShouldStop"></param> /// <returns>Return true if cancelled</returns> public static bool ForAllPermutation<T>(T[] items, Func<T[], bool> funcExecuteAndTellIfShouldStop) { int countOfItem = items.Length; if (countOfItem <= 1) { return funcExecuteAndTellIfShouldStop(items); } var indexes = new int[countOfItem]; for (int i = 0; i < countOfItem; i++) { indexes[i] = 0; } if (funcExecuteAndTellIfShouldStop(items)) { return true; } for (int i = 1; i < countOfItem;) { if (indexes[i] < i) { // On the web there is an implementation with a multiplication which should be less efficient. if ((i & 1) == 1) // if (i % 2 == 1) ... more efficient ??? At least the same. { Swap(ref items[i], ref items[indexes[i]]); } else { Swap(ref items[i], ref items[0]); } if (funcExecuteAndTellIfShouldStop(items)) { return true; } indexes[i]++; i = 1; } else { indexes[i++] = 0; } } return false; } /// <summary> /// This function is to show a linq way but is far less efficient /// </summary> /// <typeparam name="T"></typeparam> /// <param name="list"></param> /// <param name="length"></param> /// <returns></returns> static IEnumerable<IEnumerable<T>> GetPermutations<T>(IEnumerable<T> list, int length) { if (length == 1) return list.Select(t => new T[] { t }); return GetPermutations(list, length - 1) .SelectMany(t => list.Where(e => !t.Contains(e)), (t1, t2) => t1.Concat(new T[] { t2 })); } /// <summary> /// Swap 2 elements of same type /// </summary> /// <typeparam name="T"></typeparam> /// <param name="a"></param> /// <param name="b"></param> [MethodImpl(MethodImplOptions.AggressiveInlining)] static void Swap<T>(ref T a, ref T b) { T temp = a; a = b; b = temp; } /// <summary> /// Func to show how to call. It does a little test for an array of 4 items. /// </summary> public static void Test() { ForAllPermutation("123".ToCharArray(), (vals) => { Debug.Print(String.Join("", vals)); return false; }); int[] values = new int[] { 0, 1, 2, 4 }; Debug.Print("Non Linq"); ForAllPermutation(values, (vals) => { Debug.Print(String.Join("", vals)); return false; }); Debug.Print("Linq"); foreach(var v in GetPermutations(values, values.Length)) { Debug.Print(String.Join("", v)); } // Performance int count = 0; values = new int[10]; for(int n = 0; n < values.Length; n++) { values[n] = n; } Stopwatch stopWatch = new Stopwatch(); stopWatch.Reset(); stopWatch.Start(); ForAllPermutation(values, (vals) => { foreach(var v in vals) { count++; } return false; }); stopWatch.Stop(); Debug.Print($"Non Linq {count} items in {stopWatch.ElapsedMilliseconds} millisecs"); count = 0; stopWatch.Reset(); stopWatch.Start(); foreach (var vals in GetPermutations(values, values.Length)) { foreach (var v in vals) { count++; } } stopWatch.Stop(); Debug.Print($"Linq {count} items in {stopWatch.ElapsedMilliseconds} millisecs"); } } } 

Comments

1

Lists permutations of a string. Avoids duplication when characters are repeated:

using System; using System.Collections; class Permutation{ static IEnumerable Permutations(string word){ if (word == null || word.Length <= 1) { yield return word; yield break; } char firstChar = word[0]; foreach( string subPermute in Permutations (word.Substring (1)) ) { int indexOfFirstChar = subPermute.IndexOf (firstChar); if (indexOfFirstChar == -1) indexOfFirstChar = subPermute.Length; for( int index = 0; index <= indexOfFirstChar; index++ ) yield return subPermute.Insert (index, new string (firstChar, 1)); } } static void Main(){ foreach( var permutation in Permutations ("aab") ) Console.WriteLine (permutation); } } 

2 Comments

With so many working solutions already present, you may want to describe what makes your solution stand out from all the other solutions here.
Avoids duplication when characters are repeated (by chindirala for another answer). For "aab": aab aba baa
1

Many of the implementations provided here aren't reusable because they hard-code what to do with the results (like calling Console.WriteLine) directly in the middle of the function. This means that every time you want to use permutations different data and use it in another context you have to reimplement the algorithm.

Instead it is better to have an implementation that returns a collection of results. Because there are a large number of potential results, it could consume a lot of memory, so using a generator which only returns results one by one is preferred.

Here is a short implementation implemented as a generic generator. A generator returns values as they are requested, so much less space is consumed, and if the results are never consumed there is minimal cost to calling the function.

In general when using generators it is good practice to not modify data, so there is a wrapper function which works on immutable data, which makes a temporary array to perform the mutations on. This has an advantage of making it thread safe, and assuring that if the enumeration is interrupted the original data is not corrupted.

The principle of the algorithm is hopefully clear from the implementation. The input array is the first permutation. You can generate additional permutations by swapping one item in the list with another item in the list, and then permuting all of the other remaining items in the list.

 public static IEnumerable<T[]> PermutationsInPlace<T>(this T[] self, int from = 0) { if (from == self.Length - 1) yield return self; for (var i = from; i < self.Length; i++) { (self[from], self[i]) = (self[i], self[from]); foreach (var p in self.PermutationsInPlace(from + 1)) yield return p; (self[from], self[i]) = (self[i], self[from]); } } public static IEnumerable<T[]> Permutations<T>(this IReadOnlyList<T> self) => self.ToArray().PermutationsInPlace(); 

Comments

0
class Permutation { public static List<string> Permutate(string seed, List<string> lstsList) { loopCounter = 0; // string s="\w{0,2}"; var lstStrs = PermuateRecursive(seed); Trace.WriteLine("Loop counter :" + loopCounter); return lstStrs; } // Recursive function to find permutation private static List<string> PermuateRecursive(string seed) { List<string> lstStrs = new List<string>(); if (seed.Length > 2) { for (int i = 0; i < seed.Length; i++) { str = Swap(seed, 0, i); PermuateRecursive(str.Substring(1, str.Length - 1)).ForEach( s => { lstStrs.Add(str[0] + s); loopCounter++; }); ; } } else { lstStrs.Add(seed); lstStrs.Add(Swap(seed, 0, 1)); } return lstStrs; } //Loop counter variable to count total number of loop execution in various functions private static int loopCounter = 0; //Non recursive version of permuation function public static List<string> Permutate(string seed) { loopCounter = 0; List<string> strList = new List<string>(); strList.Add(seed); for (int i = 0; i < seed.Length; i++) { int count = strList.Count; for (int j = i + 1; j < seed.Length; j++) { for (int k = 0; k < count; k++) { strList.Add(Swap(strList[k], i, j)); loopCounter++; } } } Trace.WriteLine("Loop counter :" + loopCounter); return strList; } private static string Swap(string seed, int p, int p2) { Char[] chars = seed.ToCharArray(); char temp = chars[p2]; chars[p2] = chars[p]; chars[p] = temp; return new string(chars); } } 

Comments

0

Here's my solution in JavaScript (NodeJS). The main idea is that we take one element at a time, "remove it" from the string, vary the rest of the characters, and insert the element at the front.

function perms (string) { if (string.length == 0) { return []; } if (string.length == 1) { return [string]; } var list = []; for(var i = 0; i < string.length; i++) { var invariant = string[i]; var rest = string.substr(0, i) + string.substr(i + 1); var newPerms = perms(rest); for (var j = 0; j < newPerms.length; j++) { list.push(invariant + newPerms[j]); } } return list; } module.exports = perms; 

And here are the tests:

require('should'); var permutations = require('../src/perms'); describe('permutations', function () { it('should permute ""', function () { permutations('').should.eql([]); }) it('should permute "1"', function () { permutations('1').should.eql(['1']); }) it('should permute "12"', function () { permutations('12').should.eql(['12', '21']); }) it('should permute "123"', function () { var expected = ['123', '132', '321', '213', '231', '312']; var actual = permutations('123'); expected.forEach(function (e) { actual.should.containEql(e); }) }) it('should permute "1234"', function () { // Wolfram Alpha FTW! var expected = ['1234', '1243', '1324', '1342', '1423', '1432', '2134', '2143', '2314', '2341', '2413', '2431', '3124', '3142', '3214', '3241', '3412', '3421', '4123', '4132']; var actual = permutations('1234'); expected.forEach(function (e) { actual.should.containEql(e); }) }) }) 

Comments

0

Here is the simplest solution I can think of:

let rec distribute e = function | [] -> [[e]] | x::xs' as xs -> (e::xs)::[for xs in distribute e xs' -> x::xs] let permute xs = Seq.fold (fun ps x -> List.collect (distribute x) ps) [[]] xs 

The distribute function takes a new element e and an n-element list and returns a list of n+1 lists each of which has e inserted at a different place. For example, inserting 10 at each of the four possible places in the list [1;2;3]:

> distribute 10 [1..3];; val it : int list list = [[10; 1; 2; 3]; [1; 10; 2; 3]; [1; 2; 10; 3]; [1; 2; 3; 10]] 

The permute function folds over each element in turn distributing over the permutations accumulated so far, culminating in all permutations. For example, the 6 permutations of the list [1;2;3]:

> permute [1;2;3];; val it : int list list = [[3; 2; 1]; [2; 3; 1]; [2; 1; 3]; [3; 1; 2]; [1; 3; 2]; [1; 2; 3]] 

Changing the fold to a scan in order to keep the intermediate accumulators sheds some light on how the permutations are generated an element at a time:

> Seq.scan (fun ps x -> List.collect (distribute x) ps) [[]] [1..3];; val it : seq<int list list> = seq [[[]]; [[1]]; [[2; 1]; [1; 2]]; [[3; 2; 1]; [2; 3; 1]; [2; 1; 3]; [3; 1; 2]; [1; 3; 2]; [1; 2; 3]]] 

Comments

0
 //Generic C# Method private static List<T[]> GetPerms<T>(T[] input, int startIndex = 0) { var perms = new List<T[]>(); var l = input.Length - 1; if (l == startIndex) perms.Add(input); else { for (int i = startIndex; i <= l; i++) { var copy = input.ToArray(); //make copy var temp = copy[startIndex]; copy[startIndex] = copy[i]; copy[i] = temp; perms.AddRange(GetPerms(copy, startIndex + 1)); } } return perms; } //usages char[] charArray = new char[] { 'A', 'B', 'C' }; var charPerms = GetPerms(charArray); string[] stringArray = new string[] { "Orange", "Mango", "Apple" }; var stringPerms = GetPerms(stringArray); int[] intArray = new int[] { 1, 2, 3 }; var intPerms = GetPerms(intArray); 

1 Comment

It would be great if you can elaborate a little on how this code works, instead of leaving it here alone.
0

I hope this will suffice:

using System; public class Program { public static void Main() { //Example using word cat permute("cat"); } static void permute(string word){ for(int i=0; i < word.Length; i++){ char start = word[0]; for(int j=1; j < word.Length; j++){ string left = word.Substring(1,j-1); string right = word.Substring(j); Console.WriteLine(start+right+left); } if(i+1 < word.Length){ word = wordChange(word, i + 1); } } } static string wordChange(string word, int index){ string newWord = ""; for(int i=0; i<word.Length; i++){ if(i== 0) newWord += word[index]; else if(i== index) newWord += word[0]; else newWord += word[i]; } return newWord; } 

output:

cat cta act atc tca tac 

Comments

0

Here's another appraoch that is slighly more generic.

void Main() { var perms = new Permutations<char>("abc"); perms.Generate(); } class Permutations<T> { private List<T> permutation = new List<T>(); HashSet<T> chosen; int n; List<T> sequence; public Permutations(IEnumerable<T> sequence) { this.sequence = sequence.ToList(); this.n = this.sequence.Count; chosen = new HashSet<T>(); } public void Generate() { if(permutation.Count == n) { Console.WriteLine(string.Join(",",permutation)); } else { foreach(var elem in sequence) { if(chosen.Contains(elem)) continue; chosen.Add(elem); permutation.Add(elem); Generate(); chosen.Remove(elem); permutation.Remove(elem); } } } } 

Comments

0

Here's an answer which has the following features:

  • Supports permutation WITH repetition/duplicates

  • Iterative solution (no recursion needed)

  • Short and concise, with no need of special math operators or casting

  • Uses IEnumerable, so you can keep your code neat and tidy

  • Works on ints, but you can easily use string arrays and correspond them appropriately

     static IEnumerable<int[]> permute(int size) { int[] i = new int[size]; while (true) { yield return i; int index = 0; while (index < size) { i[index]++; if (i[index] == size) { i[index] = 0; index++; } else break; } if (index == size) break; } } // Example usage: static void Main(string[] args) { foreach (int[] i in permute(3)) { foreach (int j in i) Console.Write(j + " "); Console.WriteLine(); } } 

Output:

0 0 0 1 0 0 2 0 0 0 1 0 1 1 0 2 1 0 0 2 0 1 2 0 2 2 0 0 0 1 1 0 1 2 0 1 0 1 1 1 1 1 2 1 1 0 2 1 1 2 1 2 2 1 0 0 2 1 0 2 2 0 2 0 1 2 1 1 2 2 1 2 0 2 2 1 2 2 2 2 2 

Comments

-1

Here is the function which will print all permutations recursively.

public void Permutations(string input, StringBuilder sb) { if (sb.Length == input.Length) { Console.WriteLine(sb.ToString()); return; } char[] inChar = input.ToCharArray(); for (int i = 0; i < input.Length; i++) { if (!sb.ToString().Contains(inChar[i])) { sb.Append(inChar[i]); Permutations(input, sb); RemoveChar(sb, inChar[i]); } } } private bool RemoveChar(StringBuilder input, char toRemove) { int index = input.ToString().IndexOf(toRemove); if (index >= 0) { input.Remove(index, 1); return true; } return false; } 

Comments

-1

Here is a C# answer which is a little simplified.

public static void StringPermutationsDemo() { strBldr = new StringBuilder(); string result = Permute("ABCD".ToCharArray(), 0); MessageBox.Show(result); } static string Permute(char[] elementsList, int startIndex) { if (startIndex == elementsList.Length) { foreach (char element in elementsList) { strBldr.Append(" " + element); } strBldr.AppendLine(""); } else { for (int tempIndex = startIndex; tempIndex <= elementsList.Length - 1; tempIndex++) { Swap(ref elementsList[startIndex], ref elementsList[tempIndex]); Permute(elementsList, (startIndex + 1)); Swap(ref elementsList[startIndex], ref elementsList[tempIndex]); } } return strBldr.ToString(); } static void Swap(ref char Char1, ref char Char2) { char tempElement = Char1; Char1 = Char2; Char2 = tempElement; } 

Output:

1 2 3 1 3 2 2 1 3 2 3 1 3 2 1 3 1 2 

Comments

-1

Here is one more implementation of the algo mentioned.

public class Program { public static void Main(string[] args) { string str = "abcefgh"; var astr = new Permutation().GenerateFor(str); Console.WriteLine(astr.Length); foreach(var a in astr) { Console.WriteLine(a); } //a.ForEach(Console.WriteLine); } } class Permutation { public string[] GenerateFor(string s) { if(s.Length == 1) { return new []{s}; } else if(s.Length == 2) { return new []{s[1].ToString()+s[0].ToString(),s[0].ToString()+s[1].ToString()}; } var comb = new List<string>(); foreach(var c in s) { string cStr = c.ToString(); var sToProcess = s.Replace(cStr,""); if (!string.IsNullOrEmpty(sToProcess) && sToProcess.Length>0) { var conCatStr = GenerateFor(sToProcess); foreach(var a in conCatStr) { comb.Add(c.ToString()+a); } } } return comb.ToArray(); } } 

1 Comment

new Permutation().GenerateFor("aba") outputs string[4] { "ab", "baa", "baa", "ab" }

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.