使用排列

时间:2016-06-22 19:09:53

标签: java android algorithm permutation powerset

我目前有两种方法使用递归来给出给定String的所有可能组合,我在这个answer的帮助下得到了这个。因此,如果我输入String并返回这些组合:

and
adn
dan
dna
nad
nda

但是我希望它返回该字符串中其余一两个字母的所有可能组合,如下所示:

a
n
d
an
ad 
na
nd
etc...

Something like this answer but in java

该答案还提到并链接了Powersets,它显示了a,b,c的所有可能子集:

Image

正如您所看到的那样,它不会将组合重新放到前面,例如

c,b,a
c,a,b
c,a
....

这是我想要实现的当前代码:

public void permutation(String str) {

  permutation("", str);
}

private void permutation(String prefix, String str) {

    int n = str.length();
    if (n == 0) myList.add(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 :(得分:3)

    if (n == 0) myList.add(prefix);

您提供的此声明仅在您置换了str中可用的所有字符时才添加。

如果您移除if (n == 0),则会将a的所有前缀添加到anand,因此您可以使用:

private void permutation(String prefix, String str) {
    int n = str.length();
    myList.add(prefix);
    if(n > 0) {
        for (int i = 0; i < n; i++)
            permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, n));

    }

由于递归,你显然会得到一堆重复项,可能还有一个空字符串,但是你可以使用Collection不允许重复,或者你可以在添加之前检查它是否重复。我将优化留给您。

答案 1 :(得分:3)

考虑这个问题的一种方法是考虑给定集合的所有二进制组合。

例如,如果有问题的集合是{a,b,c},那么所有二进制组合(2 ^ 3 = 8)都是:

000 = {}
001 = {c}
010 = {b}
011 = {b,c}
100 = {a}
101 = {a, c}
110 = {a, b}
111 = {a, b, c}

构建这些集合后,可以使用递归来获取每个集合的组合。

答案 2 :(得分:0)

Powerset不会回报你想要的东西。这是因为集合{a, b, c}等同于{b, a, c}以及您想拥有的其他集合。

您可以修改算法以从每个集合中创建所有可能的排列。这将为您提供一些重复项,因此您可以将它们存储在集合中。

答案 3 :(得分:-1)

public class Stringpermutations {
    public static void main(String[] args) {
        permutations(0,"123");
    }

    public static void permutations(int start, String s) {
        char[] chr=s.toCharArray();
        if(start==s.length()) {
            System.out.println(s);
        }
        for(int i=start;i<s.length();i++) {
            char c=chr[i];
            chr[i]=chr[start];
            chr[start]=c;
            permutations(start+1,new String(chr));
        } 
    }
}