找出字符串的排列总数

时间:2017-09-05 10:46:48

标签: java algorithm arraylist permutation

我正在尝试使用以下程序计算给定字符串的排列总数:

程序

    class Test{

    public static void main(String[] args){
        String str = "ABC";
        int n = str.length();

        //System.out.println(permute(str, 0, n-1));
        permute(str, 0, n-1);
    }

    private static int permute(String str, int l, int r){
        ArrayList<String> list=new ArrayList<String>();
        if (l == r)
            //System.out.println(str);
            list.add(str);
        else
        {
            for (int i = l; i <= r; i++)
            {
                str = swap(str,l,i);
                permute(str, l+1, r);
                str = swap(str,l,i);
            }
        }
        /*for (int i=0;i<list.size() ;i++ ) {
            System.out.println(list.get(i));
        }*/
        return list.size();
    } 
public static String swap(String a, int i, int j){
        char temp;
        char[] charArray = a.toCharArray();
        temp = charArray[i] ;
        charArray[i] = charArray[j];
        charArray[j] = temp;
        return String.valueOf(charArray);
    }
}

输出:0

我再次应用相同的方法来显示给定字符串的排列。以下程序显示了我的方法:

程序

    class Test{

    public static void main(String[] args){
        String str = "ABC";
        int n = str.length();

        //System.out.println(permute(str, 0, n-1));
        permute(str, 0, n-1);
    }

    private static void permute(String str, int l, int r){
        ArrayList<String> list=new ArrayList<String>();
        if (l == r)
            //System.out.println(str);
            list.add(str);
        else
        {
            for (int i = l; i <= r; i++)
            {
                str = swap(str,l,i);
                permute(str, l+1, r);
                str = swap(str,l,i);
            }
        }
        for (int i=0;i<list.size() ;i++ ) {
            System.out.println(list.get(i));
        }
        //return list.size();
    } 
public static String swap(String a, int i, int j){
        char temp;
        char[] charArray = a.toCharArray();
        temp = charArray[i] ;
        charArray[i] = charArray[j];
        charArray[j] = temp;
        return String.valueOf(charArray);
    }
}

输出

ABC
ACB
BAC
BCA
CBA
CAB

我的疑问在于,当我尝试将arraylist我的0的大小作为输出返回时,但是当我打印出list的所有元素时,它显示所有排列。

任何人都可以清楚我的怀疑吗?

1 个答案:

答案 0 :(得分:2)

在方法中创建列表是不正确的。由于递归,您将在最后获得一个空列表。 现在,你可以做的最快的修复方法就是在你的方法中传递ArrayList

 private static int permute(String str, int l, int r, ArrayList<String> list){

    if (l == r) {
        list.add(str);
    }
    else {
        for (int i = l; i <= r; i++) {
            str = swap(str,l,i);
            permute(str, l+1, r, list);
            str = swap(str,l,i);
        }
    }
    return list.size();
}

并将其称为:

    String str = "ABC";
    int n = str.length();
    ArrayList<String> list = new ArrayList<>();
    permute(str, 0, n-1, list);

    System.out.println(list.size());

现在您的输出应为6

修改

如果您只需要排列数,当然它是n!,其中n是字符串的长度。

private static long numberOfPermutations(long n) {
    if(n == 1 || n == 0) return 1;

    return (n) * numberOfPermutations(n-1);
}

以这种方式使用:

 int i = numberOfPermutations("abc".length());

 System.out.println(i);

<强>更新

作为建议,如果字符串中的chars重复,请按另一个公式n!/ (k1!*k2!*k3!...)执行。 Implimentation:

String string = "ABBCCCD";
String[] split = string.split("");

Map<String, Long> collect = Arrays.stream(split).collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));


long result = numberOfPermutations(string.length()) / collect.values().stream().map(Main::numberOfPermutations).reduce(1L, (a, b) -> a *b);
System.out.println(result);