具有重复的任何长度的排列

时间:2014-02-05 18:57:39

标签: java algorithm permutation

我试图找到给定字符串的任何长度的排列。这包括重复

例如:

str = "java";

At length 1

j, a, v, a

At length 3

4!/(4-3)! = 24 

jav, jaa, jva, jva, jaa, jav,
ajv, aja, avj, ava, aaj, aav,
vja, vja, vaj, vaa, vaj, vaa,
aja, ajv, aaj, aav, avj, ava

我在考虑使用for loop遍历字符串的每个字符并执行必要的计算以生成字符串其余部分的排列

前:

start with "j"
    av, aa | va, va | aa, av

then with the first "a"
    jv, ja | vj, va | aj, av 

这是我到目前为止所做的事情,我仍在研究解决这个问题背后的逻辑:

public static class Pair<Character, Boolean> {
    Character letter;
    Boolean used;
    Pair(Character c, Boolean seen) {
        this.used = seen;
        this.letter = c;
    }
}

public static void permutationOfString(String str, int len) {
    List<Pair> charCheck = new ArrayList<Pair>();
    for (int i = 0; i < str.length(); i++) {
        charCheck.add(new Pair(str.charAt(i), false));
    }

    for (char c : str.toCharArray()) {

    }
}   

我不确定如何写这个。我想输出字符串的所有可能的排列。

如果有人有另一种解决方法,或者可以更有效地做到这一点,我愿意接受建议!谢谢!

3 个答案:

答案 0 :(得分:1)

您可以使用Apache Commons CollectionsApache Commons Lang

String str = "java";
List<Character> strChars = Arrays.asList(ArrayUtils.toObject(str.toCharArray()));

Collection<List<Character>> charPermutations = CollectionUtils.permutations(strChars);

List<String> result = new ArrayList<>();
for (List<Character> chars : charPermutations) {
    result.add(StringUtils.join(chars, ""));
}

...或Guava Libraries

String str = "java";
List<Character> strChars = Chars.asList(str.toCharArray());

Collection<List<Character>> charPermutations = Collections2.permutations(strChars);

Collection<String> result = Collections2.transform(charPermutations, new Function<List<Character>, String>() {
    public String apply(List<Character> input) {
        return new String(Chars.toArray(input));
    }
});

然而,如果你正在使用Java 8,它可以稍微优雅地完成,然后这个疯狂(但仍然无法与Groovy的优雅相比......)

答案 1 :(得分:1)

为每一个添加一些内容以使它们独一无二 对非重复项运行常规算法 在输出结果之前去除附加的文本。

答案 2 :(得分:0)

这是一个返回int的阶乘的方法,所以你可以像这样输入字符串的长度

factorial("java".length);


public static int factorial(int n) {
    int fact = 1; // this  will be the result
    for (int i = 1; i <= n; i++) {
        fact *= i;
    }
    return fact;
}

但似乎你试图根据某个单词中的字母数量找到可能的组合数量,就像在你的例子中用java一样,它们是3个不同的字母。因此,似乎你想知道这个单词的长度有多少排列3在这种情况下,长度是指有多少可能的组合的指数。