字符串排列

时间:2013-02-01 02:54:04

标签: java string arraylist permutation recurrence

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

3 个答案:

答案 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排列解决方案......

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