我最近试图编写一个脚本,打印出Java中所有单词的排列。由于某种原因,它只打印出一个。我只是想不出来!
import java.util.*;
public class AllPermutations {
ArrayList<String> letters = new ArrayList<String>();
public void main(){
letters.add("H");
letters.add("a");
letters.add("s");
permutate("",letters);
}
public void permutate(String word, ArrayList<String> lettersLeft){
if(lettersLeft.size()==0){
System.out.println(word);
}else{
for(int i=0;i<lettersLeft.size();i++){
String newWord = new String();
newWord = word+lettersLeft.get(i);
lettersLeft.remove(i);
permutate(newWord, lettersLeft);
}
}
}
}
答案 0 :(得分:3)
您需要将已删除的字母添加回lettersLeft列表
public void permutate(String word, ArrayList<String> lettersLeft){
if(lettersLeft.size()==0){
System.out.println(word);
}else{
for(int i=0;i<lettersLeft.size();i++){
String temp = lettersLeft.remove(i);
String newWord = word+temp;
permutate(newWord, lettersLeft);
lettersLeft.add(i, temp);
}
}
}
我还没有测试过,但我认为它应该可行。
问题是Java /您通过引用传递,而不是复制(ArrayList)。因此,一旦到达递归树的底部,lettersLeft将包含0个元素,一旦你返回,它仍将有0个元素。
作为旁注,StringBuilder / StringBuffer更擅长进行字符串排列任务,因为String是不可变的,因此你浪费了很多资源来创建新的字符串,n!确切地说。两个StringBuilder / Buffer之间的区别由你来发现。
答案 1 :(得分:0)
原因是lettersLeft
总是通过引用传递。一旦你从lettersLeft删除一封信,它就会被永久删除。因此,对于第一次迭代,您打印出“HAS”。一旦完成,递归算法会备份一个级别来进行第二次迭代,但是你知道什么? lettersLeft是空的。所以它终止而不通过if语句导致它不会得到另一个词或排列。要解决此问题,请创建本地副本,就像使用newWord一样。希望有所帮助。
答案 2 :(得分:-1)
在这种情况下,您要删除Arraylist
中的字母,它会变为空,直到它到达第一个单词的结尾。然后,该列表大小始终为零... Add the removed letter back to the list
.. .........
我希望你recommend
使用下面的链接并找到String Permutations的好例子,因为有两种内存效率和空间有效的String排列解决方案......