我正在尝试设计一个基本上如下的函数:
String s =“BLAH”;
将以下内容存储到数组中: 胡说 啦 呸 BLH BLA BL BA BH 啊 人
所以基本上我在那里做的就是一次一个地减去每个字母。然后一次减去两个字母的组合,直到剩下2个字符。将这些代中的每一代存储在一个数组中。
希望这是有道理的,
杰克
答案 0 :(得分:2)
你是怎么得到'al'的?这些混在一起吗?
我会创建一个HashSet来保存所有排列并将其传递给递归方法。
void foo(HastSet<String> set, String string) {
if (string.length < 2) // base case
return
else {
// add the string to the hashset
set.add(string);
// go through each character
for (int i = 0; i < string.length; i++) {
String newString = s.substring(0,i)+s.substring(i+1);
foo(set, newString);
}
}
}
如果您关心唯一性,那就是这样。如果没有,您可以使用Vector。无论哪种方式,您都可以使用toArray来恢复阵列。
答案 1 :(得分:1)
这是@ voodoogiant答案的优化。基本上我想推迟单词构建任务,直到递归的基本情况。这样你就可以使用StringBuilder来构建单词。所以递归的作用基本上是打开和关闭一个布尔数组的位,这个位说明是否必须在下一个单词中使用某个字母。
暂时没有编写java代码,如果没有编译的话,请原谅我。
void buildWords(String baseWord, boolean[] usedLetters, HashSet<String> words, int index){
if (index == baseWord.length()){
StringBuilder builder = new StringBuilder();
for (int i = 0; i < index; i++){
if (usedLetters[i])
builder.append(baseWord.characterAt(i));
}
words.add(builder.toString());
}
else{
usedLetters[index] = true;
buildWords(baseWord, usedLetters, words, index+1);
usedLetters[index] = false;
buildWords(baseWord, usedLetters, words, index+1);
}
}
你需要注意的事情:
答案 2 :(得分:0)
你真的不需要递归来做这件事。这是一个迭代算法:
String master = "abcd";
final int L = master.length();
List<String> list = new ArrayList<String>();
list.add(master);
Set<String> current = new HashSet<String>(list);
for (int i = L-1; i >= 2; i--) {
Set<String> next = new HashSet<String>();
for (String s : current) {
for (int k = 0; k < s.length(); k++) {
next.add(s.substring(0, k) + s.substring(k + 1));
}
}
list.addAll(current = next);
}
System.out.println(list);
// prints "[abcd, abc, abd, bcd, acd, ac, ad, ab, bc, bd, cd]"
这基本上是breadth-first search的核心。您从最初包含current
的{{1}}集开始。然后在String master
的每次迭代中,您都会浏览i
并生成for (String s : current)
集合,您可以通过从next
删除所有可能的字符来完成此操作。
有效的Java第2版:第25项:首选列表到数组,但如果您坚持存储在s
,则可以在最后执行以下操作。
String[]