Anagram算法在100%的时间内不起作用

时间:2015-04-03 10:22:03

标签: java algorithm recursion factorial anagram

这是我的anagram算法

   public static void anagram() {
    String word = JOptionPane.showInputDialog("Enter the word");
    char[] wordArray = word.toCharArray();
    ArrayList<Integer> noOfRL = new ArrayList<>();
    int repeatedLetters = 1;
    for (int i = 0; i < word.length(); i++) {
        for (int k = i+1; k < word.length()-1; k++) {
            if (wordArray[i] == wordArray[k]) {
                repeatedLetters++;
                wordArray[k] = (char) (i+k);
            }

        }
        if (repeatedLetters != 1) {
            noOfRL.add(repeatedLetters);
        }
        repeatedLetters = 1;
    }
    double totalCombinations = factorial(word.length());
    double restrictions  = 1;
    for(int i = 0; i < noOfRL.size(); i++){
        restrictions *= factorial(noOfRL.get(i));
    }
    double actualCombinations = totalCombinations/restrictions;
    System.out.println(actualCombinations);

}

public static double factorial(double number) {
    if (number > 1) {
        return number * factorial(number - 1);
    } else {
        return 1;

    }
}

它适用于所有正常单词。 但是只要你输入eeeeeee或aaaaaaaa。等等... 代码无法给出1的正确答案。 经过调试后,我意识到重复字母的数量总是比字符串长度少1,因此给出了错误的答案。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

我会说,你的嵌套for循环是不必要的复杂。 您可以使用流来聚合相同的字母,并通过因子函数减小结果列表的大小。 结果可能如下所示:

public static void anagram() {
    final String word = JOptionPane.showInputDialog("Enter the word");
    final double restrictions = com.google.common.primitives.Chars
            .asList(word.toCharArray())
            .stream()
            .collect(
                    collectingAndThen(
                            groupingBy(Function.identity()),
                            map -> map.values().stream()
                                    .mapToDouble(List::size)
                                    .filter(l -> l > 1)
                                    .reduce(1, (a, b) -> a * factorial(b))));
    final double totalCombinations = factorial(word.length());
    final double actualCombinations = totalCombinations / restrictions;
    System.out.println(actualCombinations);
}