2013-02-01 89 views
0

我最近试图编写一个脚本来打印出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

你需要复制'lettersLeft'列表而不是直接修改它? –

+1

你能举一个你期待什么的例子,以及实际的结果。 – Siddharth

+0

难道你不应该有一个for循环运行permutate nPm次? – Siddharth

回答

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之间的差异由您来发现。

0

原因是lettersLeft总是被引用引用。一旦你从lettersLeft中删除一封信件,它将被永久删除。因此,对于第一次迭代,您已经打印出“HAS”。一旦完成,递归算法会备份一个级别以进行第二次迭代,但是您知道什么? lettersLeft为空。因此它会在不传递if语句的情况下终止,导致它不会获得另一个单词或置换。为了解决这个问题,创建一个本地副本,就像你使用newWord一样。希望有所帮助。

-1

在这种情况下,您将从Arraylist中删除字母,并且它会变为空,直到它到达第一个单词的末尾。然后,在此之后,列表大小始终为零... Add the removed letter back to the list ......... ..

我会recommend你使用下面的链接,找到字符串置换的很好的例子,因为有两个储存串排列的效率和空间效率的解决方案......

http://www.codingeek.com/java/strings/find-all-possible-permutations-of-string-using-recursive-method/