java字符串排列和组合查找

java字符串排列和组合查找,java,algorithm,permutation,combinations,Java,Algorithm,Permutation,Combinations,我正在写一个Android word应用程序。我的代码包含一个方法,该方法将查找长度至少为3的7个字母字符串的字符串和子字符串的所有组合。然后将所有可用的组合与词典中的每个单词进行比较,以找到所有有效的单词。我使用的是递归方法。这是密码 // Gets all the permutations of a string. void permuteString(String beginningString, String endingString) { if (endingString.le

我正在写一个Android word应用程序。我的代码包含一个方法,该方法将查找长度至少为3的7个字母字符串的字符串和子字符串的所有组合。然后将所有可用的组合与词典中的每个单词进行比较,以找到所有有效的单词。我使用的是递归方法。这是密码

// Gets all the permutations of a string.
void permuteString(String beginningString, String endingString) {
    if (endingString.length() <= 1){
        if((Arrays.binarySearch(mDictionary, beginningString.toLowerCase() +   endingString.toLowerCase())) >= 0){
            mWordSet.add(beginningString + endingString);
        }
    }
    else
        for (int i = 0; i < endingString.length(); i++) {
            String newString = endingString.substring(0, i) + endingString.substring(i + 1);
            permuteString(beginningString + endingString.charAt(i), newString);
      }
}
// Get the combinations of the sub-strings. Minimum 3 letter combinations
void subStrings(String s){
    String newString = "";
    if(s.length() > 3){
        for(int x = 0; x < s.length(); x++){
            newString = removeCharAt(x, s);
            permuteString("", newString);
            subStrings(newString);
        }
    }
}
//获取字符串的所有排列。
void permuteString(字符串开始字符串、字符串结束字符串){
if(endingString.length()=0){
添加(开始字符串+结束字符串);
}
}
其他的
对于(int i=0;i3){
对于(int x=0;x
上面的代码运行良好,但当我在NexusS上安装它时,我意识到它运行有点太慢了。需要几秒钟才能完成。大约3或4秒,这是不可接受的。 现在我在手机上玩了一些文字游戏,他们会立即计算出字符串的所有组合,这让我相信我的算法不是很有效,可以改进。有人能帮忙吗


公共类三节点{
三节点a、b、c、d、e、f、g、h、i、j、k、l、m、n、o、p、q、r、s、t、u、v、w、x、y、z;
三元组[]儿童={a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z};
private ArrayList words=new ArrayList();
公共无效添加字(字符串字){
添加(word);
}
公共数组列表getWords(){
返回单词;
}
}

公共类Trie{
静态字符串myWord;
静态字符串myLetters=“afinntry”;
静态字符[]myChars;
静态排序;
静态三节点myNode=新三节点();
静态三极电流节点;
静态int y=0;
静态ArrayList availableWords=新ArrayList();
公共静态void main(字符串[]args){
readWords();
getPermutations();
}
公共静态void getPermutations(){
currentNode=myNode;
对于(int x=0;x=myChars.length){
node.addWord(myWord);
//System.out.println(node.getWords()+“”+y);
y++;
返回;
}
if(node.children[myChars[x]-'a']==null){
插入(node.children[myChars[x]-'a']=newtrinode(),myChars,x=x+1);
}否则{
插入(node.children[myChars[x]-'a'],myChars,x=x+1);
}
}
}
使用


而不是测试所有N!可能的情况下,您只能遵循导致结果的前缀树。这将大大减少您要检查的字符串数量。

在当前方法中,您要查找每个子字符串的每个排列。因此,对于
“abc”
,您需要查找
“abc”
“acb”
“bac”
“bca”
“cab”
“cba”
。如果你想找到“排列”的所有排列,你的查找次数几乎是500000000,这是在你还没看过它的子串之前。但是我们可以通过对字典进行预处理,将其缩减为一次查找,而不考虑长度

其思想是将字典中的每个单词放入某种数据结构中,其中每个元素包含一组字符,以及一个包含(仅)这些字符的所有单词的列表。例如,您可以构建一个二叉树,其中有一个节点包含(排序)字符集
“abd”
和单词列表
[“bad”,“dab”]
。现在,如果我们想找到
“dba”
的所有排列,我们将其排序为
“abd”
,并在树中查找以检索列表

正如鲍曼所指出的那样,计算机非常适合存储此类数据。trie的优点在于查找时间仅取决于搜索字符串的长度——它与词典的大小无关。由于您将存储相当多的单词,并且大多数搜索字符串都很小(大多数是递归最低级别的3个字符的子字符串),因此这种结构非常理想

在这种情况下,trie中的路径将反映字符集,而不是单词本身。因此,如果您的整个字典都是
[“bad”、“dab”、“cab”、“cable”]
,那么您的查找结构最终会是这样的:

在您实现这一点的方式中有一点时间/空间的权衡。在最简单(也是最快)的方法中,每个
节点
只包含单词列表和子节点的数组
节点[26]
。这允许您通过查看
子对象[s.charAt(i)-'a']
(其中
s
是您的搜索标准),在固定时间内找到您要查找的子对象
public class TrieNode {
TrieNode a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;
TrieNode[] children = {a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z};
private ArrayList<String> words = new ArrayList<String>();

public void addWord(String word){
    words.add(word);
}
public ArrayList<String> getWords(){
    return words;
}
}
public class Trie {

static String myWord;
static String myLetters = "afinnrty";
static char[] myChars;
static Sort sort;
static TrieNode myNode = new TrieNode();
static TrieNode currentNode;
static int y = 0;
static ArrayList<String> availableWords = new ArrayList<String>();

public static void main(String[] args) {

    readWords();
    getPermutations();
}
public static void getPermutations(){
    currentNode = myNode;
    for(int x = 0; x < myLetters.length(); x++){
        if(currentNode.children[myLetters.charAt(x) - 'a'] != null){
            //availableWords.addAll(currentNode.getWords());
            currentNode = currentNode.children[myLetters.charAt(x) - 'a'];
            System.out.println(currentNode.getWords() + "" + myLetters.charAt(x));
        }
    }
    //System.out.println(availableWords);
}
public static void readWords(){
    try {
        BufferedReader in = new BufferedReader(new FileReader("c://scrabbledictionary.txt"));
        String str;
        while ((str = in.readLine()) != null) {
            myWord = str;
            myChars = str.toCharArray();
            sort = new Sort(myChars);
            insert(myNode, myChars, 0);
        }
        in.close();
    } catch (IOException e) {
    }
}
public static void insert(TrieNode node, char[] myChars, int x){    
    if(x >= myChars.length){
        node.addWord(myWord);
        //System.out.println(node.getWords()+""+y);
        y++;
        return;
    }
    if(node.children[myChars[x]-'a'] == null){
        insert(node.children[myChars[x]-'a'] = new TrieNode(), myChars, x=x+1);
    }else{
        insert(node.children[myChars[x]-'a'], myChars, x=x+1);
    }
}
}
  static List<String> permutations(String a) {
    List<String> result=new LinkedList<String>();
    int len = a.length();
    if (len<=1){
      result.add(a);
    }else{
      for (int i=0;i<len; i++){
        for (String it:permutations(a.substring(0, i)+a.substring(i+1))){
          result.add(a.charAt(i)+it);
        }
      }
    }
    return result;
  }
public class PermutationString {

    private final String innerString;

    public PermutationString(String innerString) {
        this.innerString = innerString;
    }

    @Override
    public int hashCode() {
        int hash = 0x00;
        String s1 = this.innerString;
        for(int i = 0; i < s1.length(); i++) {
            hash += s1.charAt(i);
        }
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final PermutationString other = (PermutationString) obj;
        int nChars = 26;
        int[] chars = new int[nChars];
        String s1 = this.innerString;
        String s2 = other.innerString;
        if(s1.length() != s2.length()) {
            return false;
        }
        for(int i = 0; i < s1.length(); i++) {
            chars[s1.charAt(i)-'a']++;
        }
        for(int i = 0; i < s2.length(); i++) {
            chars[s2.charAt(i)-'a']--;
        }
        for(int i = 0; i < nChars; i++) {
            if(chars[i] != 0x00) {
                return false;
            }
        }
        return true;
    }

}
HashMap<PermutationString,ArrayList<String>> hm = new HashMap<PermutationString,ArrayList<String>>();
String[] dictionary = new String[] {"foo","bar","oof"};
ArrayList<String> items;
for(String s : dictionary) {
    PermutationString ps = new PermutationString(s);
    if(hm.containsKey(ps)) {
        items = hm.get(ps);
        items.add(s);
    } else {
        items = new ArrayList<String>();
        items.add(s);
        hm.put(ps,items);
    }
}
hm.get(new PermutationString("ofo"));
HashMap<PermutationString, ArrayList<String>> hm = new HashMap<PermutationString, ArrayList<String>>();
String[] dictionary = new String[]{"foo", "bar", "oof"};
ArrayList<String> items;
for (String s : dictionary) {
    PermutationString ps = new PermutationString(s);
    if (hm.containsKey(ps)) {
        items = hm.get(ps);
        items.add(s);
    } else {
        items = new ArrayList<String>();
        items.add(s);
        hm.put(ps, items);
    }
}
Assert.assertNull(hm.get(new PermutationString("baa")));
Assert.assertNull(hm.get(new PermutationString("brr")));
Assert.assertNotNull(hm.get(new PermutationString("bar")));
Assert.assertEquals(1,hm.get(new PermutationString("bar")).size());
Assert.assertNotNull(hm.get(new PermutationString("rab")));
Assert.assertEquals(1,hm.get(new PermutationString("rab")).size());
Assert.assertNotNull(hm.get(new PermutationString("foo")));
Assert.assertEquals(2,hm.get(new PermutationString("foo")).size());
Assert.assertNotNull(hm.get(new PermutationString("ofo")));
Assert.assertEquals(2,hm.get(new PermutationString("ofo")).size());
Assert.assertNotNull(hm.get(new PermutationString("oof")));
Assert.assertEquals(2,hm.get(new PermutationString("oof")).size());