找出弦的所有排列的优雅方法是什么。例如,ba的排列,将是ba和ab,但更长的字符串,如abcdefgh?是否有Java实现示例?


当前回答

Java中一个非常基本的解决方案是使用递归+设置(以避免重复),如果你想存储和返回解决方案字符串:

public static Set<String> generatePerm(String input)
{
    Set<String> set = new HashSet<String>();
    if (input == "")
        return set;

    Character a = input.charAt(0);

    if (input.length() > 1)
    {
        input = input.substring(1);

        Set<String> permSet = generatePerm(input);

        for (String x : permSet)
        {
            for (int i = 0; i <= x.length(); i++)
            {
                set.add(x.substring(0, i) + a + x.substring(i));
            }
        }
    }
    else
    {
        set.add(a + "");
    }
    return set;
}

其他回答

public class StringPermutation {

// Function to print all the permutations of str
static void printPermutn(String str, String ans) {

    // If string is empty
    if (str.length() == 0) {
        System.out.print(ans + " ");
        return;
    }

    for (int i = 0; i < str.length(); i++) {

        // ith character of str
        char ch = str.charAt(i);

        // Rest of the string after excluding
        // the ith character
        String ros = str.substring(0, i) + str.substring(i + 1);

        // Recurvise call
        printPermutn(ros, ans + ch);
    }
}


public static void main(String[] args) {
    String s = "ABC";
    printPermutn(s, "");
}

}

使用位操作可以很容易地做到这一点。“我们都知道,任何给定的有N个元素的集合有2N个可能的子集。如果我们用一个位来表示子集中的每个元素呢?位可以是0或1,因此我们可以用它来表示对应的元素是否属于这个给定的子集。所以每个位模式代表一个子集。”(复制文本)

private void getPermutation(String str)
        {
            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
                for(int j = 0;j < str.length() ;++j){
                    if((i & (1 << j))>0){  // to check whether jth bit is set
                        strB.append(str.charAt(j));
                    }
                }
                if(!strB.toString().isEmpty())
                    StrList.add(strB.toString());
            }
            System.out.println(Arrays.toString(StrList.toArray()));
        }

基于Mark Byers的回答,我想出了这个解决方案:

JAVA

public class Main {

    public static void main(String[] args) {
        myPerm("ABCD", 0);
    }

    private static void myPerm(String str, int index)
    {
        if (index == str.length()) System.out.println(str);

        for (int i = index; i < str.length(); i++)
        {
            char prefix = str.charAt(i);
            String suffix = str.substring(0,i) + str.substring(i+1);

            myPerm(prefix + suffix, index + 1);
        }
    }
}

C#

我还使用新的c# 8.0范围操作符在c#中编写了该函数

    class Program
    {
        static void Main(string[] args)
        {
            myPerm("ABCD", 0);
        }

        private static void myPerm(string str, int index)
        {
            if (index == str.Length) Console.WriteLine(str);

            for (int i = index; i < str.Length; i++)
            {
                char prefix = str[i];
                string suffix = str[0..i] + str[(i + 1)..];

                myPerm(prefix + suffix, index + 1);
            }
        }
    

我们只是把每个字母放在开头,然后排列。 第一次迭代是这样的:

/*
myPerm("ABCD",0)  
  prefix = "A"  
  suffix = "BCD"  
  myPerm("ABCD",1)  
    prefix = "B"  
    suffix = "ACD"  
    myPerm("BACD",2)  
      prefix = "C"  
      suffix = "BAD"  
      myPerm("CBAD",3)  
        prefix = "D"  
        suffix = "CBA"  
        myPerm("DCBA",4)  
          Console.WriteLine("DCBA")
*/

使用递归。

当输入是空字符串时,唯一的排列就是空字符串。尝试将字符串中的每个字母作为第一个字母,然后使用递归调用找到其余字母的所有排列。

import java.util.ArrayList;
import java.util.List;

class Permutation {
    private static List<String> permutation(String prefix, String str) {
        List<String> permutations = new ArrayList<>();
        int n = str.length();
        if (n == 0) {
            permutations.add(prefix);
        } else {
            for (int i = 0; i < n; i++) {
                permutations.addAll(permutation(prefix + str.charAt(i), str.substring(i + 1, n) + str.substring(0, i)));
            }
        }
        return permutations;
    }

    public static void main(String[] args) {
        List<String> perms = permutation("", "abcd");

        String[] array = new String[perms.size()];
        for (int i = 0; i < perms.size(); i++) {
            array[i] = perms.get(i);
        }

        int x = array.length;

        for (final String anArray : array) {
            System.out.println(anArray);
        }
    }
}

使用递归。

依次尝试每个字母作为第一个字母,然后使用递归调用找到剩余字母的所有排列。 基本情况是,当输入是空字符串时,唯一的排列就是空字符串。