Listing all permutations of a string/integer

后端 未结 29 1989
没有蜡笔的小新
没有蜡笔的小新 2020-11-22 00:44

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

相关标签:
29条回答
  • 2020-11-22 01:26

    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;
        }
    }
    
    0 讨论(0)
  • 2020-11-22 01:26
    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);
        }
    }
    
    0 讨论(0)
  • 2020-11-22 01:27

    Here's a good article covering three algorithms for finding all permutations, including one to find the next permutation.

    http://www.cut-the-knot.org/do_you_know/AllPerm.shtml

    C++ and Python have built-in next_permutation and itertools.permutations functions respectively.

    0 讨论(0)
  • 2020-11-22 01:28

    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]]]
    
    0 讨论(0)
  • 2020-11-22 01:29

    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);
      }
    }
    
    0 讨论(0)
  • 2020-11-22 01:30

    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;
        }
    
    0 讨论(0)
提交回复
热议问题