这是我的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,因此给出了错误的答案。
我该如何解决这个问题?
答案 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);
}