生成一定长度的所有排列

时间:2016-02-10 18:44:54

标签: java recursion permutation

假设我们有一个字母“abcdefghiklimnop”。如何以有效的方式以五组为单位递归地重复生成排列?

我几天来一直在努力解决这个问题。任何反馈都会有所帮助。

基本上这与:Generating all permutations of a given string

相同

但是,我只想要整个字符串的五十个长度的排列。我无法弄清楚这一点。

对于“abcdefghiklimnop”长度为5的所有子串,找到子串的排列。例如,如果子字符串是abcdef,我想要它的所有排列,或者如果子字符串是defli,我会想要该子字符串的所有排列。下面的代码给出了字符串的所有排列,但我想用它来查找字符串大小为5的所有子字符串的所有排列。

    public static void permutation(String str) { 
    permutation("", str); 
}
private static void permutation(String prefix, String str) {
    int n = str.length();
    if (n == 0) System.out.println(prefix);
    else {
        for (int i = 0; i < n; i++)
            permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, n));
    }
}

4 个答案:

答案 0 :(得分:6)

为了从字符串中递归选取五个字符,请遵循一个简单的算法:

  • 你的方法到目前为止应该填写一部分,并且五字符排列中的第一个位置需要一个字符
  • 如果第一个需要角色的位置超过五个,你就完成了;打印到目前为止的组合,并返回
  • 否则,将每个字符放入置换中的当前位置,并进行递归调用

这在Java中要短得多:

private static void permutation(char[] perm, int pos, String str) {
    if (pos == perm.length) {
        System.out.println(new String(perm));
    } else {
        for (int i = 0 ; i < str.length() ; i++) {
            perm[pos] = str.charAt(i);
            permutation(perm, pos+1, str);
        }
    }
}

调用者通过更改perm中的元素数来控制所需的排列长度:

char[] perm = new char[5];
permutation(perm, 0, "abcdefghiklimnop");

Demo.

答案 1 :(得分:0)

每个排列的前五个字符的集合中将包含五个字符的所有排列。例如,如果你想要四个字符串的所有两个字符排列&#39; abcd&#39;你可以从所有排列中获得它们: &#39; abcd&#39;,&#39; abdc&#39;,&#39; acbd&#39;,&#39; acdb&#39; ......&#39; dcba&#39;

因此,在检查是否已存储该排列之后,您可以将它们存储到列表中,而不是在方法中打印它们。该列表可以传入函数或静态字段,具体取决于您的规范。

答案 2 :(得分:0)

这可以使用位操作轻松完成。

private void getPermutation(String str, int length)
        {
            if(str==null)
                return;
            Set<String> StrList = new HashSet<String>();
            StringBuilder strB= new StringBuilder();
            for(int i = 0;i < (1 << str.length()); ++i)
            {
                strB.setLength(0); //clear the StringBuilder
                if(getNumberOfOnes(i)==length){
                  for(int j = 0;j < str.length() ;++j){
                    if((i & (1 << j))>0){  // to check whether jth bit is set (is 1 or not)
                        strB.append(str.charAt(j));
                    }
                }
                StrList.add(strB.toString());
                }
            }
            System.out.println(Arrays.toString(StrList.toArray()));
        }

    private int getNumberOfOnes (int n) // to count how many numbers of 1 in binary representation of n
    {
        int count=0;
        while( n>0 )
        {
        n = n&(n-1);
           count++;
        }
        return count;
    }

答案 3 :(得分:0)

class StringPermutationOfKLength
{
    // The main recursive method
    // to print all possible
    // strings of length k
    static void printAllKLengthRec(char[] set,String prefix,
                                   int n, int k)
    {

        // Base case: k is 0,
        // print prefix
        if (k == 0)
        {
            System.out.println(prefix);
            return;
        }

        // One by one add all characters
        // from set and recursively
        // call for k equals to k-1
        for (int i = 0; i < n; i++)
        {

            // Next character of input added
            String newPrefix = prefix + set[i];

            // k is decreased, because
            // we have added a new character
            printAllKLengthRec(set, newPrefix,
                n, k - 1);
        }
    }

    // Driver Code
    public static void main(String[] args)
    {
        System.out.println("First Test");
        char[] set1 = {'a', 'b','c', 'd'};
        int k = 2;
        printAllKLengthRec(set1, "", set1.length, k);

        System.out.println("\nSecond Test");
        char[] set2 = {'a', 'b', 'c', 'd'};
        k = 1;
        printAllKLengthRec(set2, "", set2.length, k);
    }