Generate list of all possible permutations of a string

后端 未结 30 2547
故里飘歌
故里飘歌 2020-11-22 15:10

How would I go about generating a list of all possible permutations of a string between x and y characters in length, containing a variable list of characters.

Any l

相关标签:
30条回答
  • 2020-11-22 15:20

    Here's a non-recursive version I came up with, in javascript. It's not based on Knuth's non-recursive one above, although it has some similarities in element swapping. I've verified its correctness for input arrays of up to 8 elements.

    A quick optimization would be pre-flighting the out array and avoiding push().

    The basic idea is:

    1. Given a single source array, generate a first new set of arrays which swap the first element with each subsequent element in turn, each time leaving the other elements unperturbed. eg: given 1234, generate 1234, 2134, 3214, 4231.

    2. Use each array from the previous pass as the seed for a new pass, but instead of swapping the first element, swap the second element with each subsequent element. Also, this time, don't include the original array in the output.

    3. Repeat step 2 until done.

    Here is the code sample:

    function oxe_perm(src, depth, index)
    {
        var perm = src.slice();     // duplicates src.
        perm = perm.split("");
        perm[depth] = src[index];
        perm[index] = src[depth];
        perm = perm.join("");
        return perm;
    }
    
    function oxe_permutations(src)
    {
        out = new Array();
    
        out.push(src);
    
        for (depth = 0; depth < src.length; depth++) {
            var numInPreviousPass = out.length;
            for (var m = 0; m < numInPreviousPass; ++m) {
                for (var n = depth + 1; n < src.length; ++n) {
                    out.push(oxe_perm(out[m], depth, n));
                }
            }
        }
    
        return out;
    }
    
    0 讨论(0)
  • 2020-11-22 15:21
    import java.util.*;
    
    public class all_subsets {
        public static void main(String[] args) {
            String a = "abcd";
            for(String s: all_perm(a)) {
                System.out.println(s);
            }
        }
    
        public static Set<String> concat(String c, Set<String> lst) {
            HashSet<String> ret_set = new HashSet<String>();
            for(String s: lst) {
                ret_set.add(c+s);
            }
            return ret_set;
        }
    
        public static HashSet<String> all_perm(String a) {
            HashSet<String> set = new HashSet<String>();
            if(a.length() == 1) {
                set.add(a);
            } else {
                for(int i=0; i<a.length(); i++) {
                    set.addAll(concat(a.charAt(i)+"", all_perm(a.substring(0, i)+a.substring(i+1, a.length()))));
                }
            }
            return set;
        }
    }
    
    0 讨论(0)
  • 2020-11-22 15:22

    Well here is an elegant, non-recursive, O(n!) solution:

    public static StringBuilder[] permutations(String s) {
            if (s.length() == 0)
                return null;
            int length = fact(s.length());
            StringBuilder[] sb = new StringBuilder[length];
            for (int i = 0; i < length; i++) {
                sb[i] = new StringBuilder();
            }
            for (int i = 0; i < s.length(); i++) {
                char ch = s.charAt(i);
                int times = length / (i + 1);
                for (int j = 0; j < times; j++) {
                    for (int k = 0; k < length / times; k++) {
                        sb[j * length / times + k].insert(k, ch);
                    }
                }
            }
            return sb;
        }
    
    0 讨论(0)
  • 2020-11-22 15:24

    The pythonic solution:

    from itertools import permutations
    s = 'ABCDEF'
    p = [''.join(x) for x in permutations(s)]
    
    0 讨论(0)
  • 2020-11-22 15:26

    This code in python, when called with allowed_characters set to [0,1] and 4 character max, would generate 2^4 results:

    ['0000', '0001', '0010', '0011', '0100', '0101', '0110', '0111', '1000', '1001', '1010', '1011', '1100', '1101', '1110', '1111']

    def generate_permutations(chars = 4) :
    
    #modify if in need!
        allowed_chars = [
            '0',
            '1',
        ]
    
        status = []
        for tmp in range(chars) :
            status.append(0)
    
        last_char = len(allowed_chars)
    
        rows = []
        for x in xrange(last_char ** chars) :
            rows.append("")
            for y in range(chars - 1 , -1, -1) :
                key = status[y]
                rows[x] = allowed_chars[key] + rows[x]
    
            for pos in range(chars - 1, -1, -1) :
                if(status[pos] == last_char - 1) :
                    status[pos] = 0
                else :
                    status[pos] += 1
                    break;
    
        return rows
    
    import sys
    
    
    print generate_permutations()
    

    Hope this is of use to you. Works with any character, not only numbers

    0 讨论(0)
  • 2020-11-22 15:27
    def permutation(str)
      posibilities = []
      str.split('').each do |char|
        if posibilities.size == 0
          posibilities[0] = char.downcase
          posibilities[1] = char.upcase
        else
          posibilities_count = posibilities.length
          posibilities = posibilities + posibilities
          posibilities_count.times do |i|
            posibilities[i] += char.downcase
            posibilities[i+posibilities_count] += char.upcase
          end
        end
      end
      posibilities
    end
    

    Here is my take on a non recursive version

    0 讨论(0)
提交回复
热议问题