给出一串单词,在字典中查找所有单词

时间:2015-07-25 05:10:43

标签: java

我正在尝试编写一个program,它会找到可以使用从arrayList加载到file的字典中构建的所有单词。 sowpodsList是存储为arrayList的字典。我希望通过字典中的每个单词iterate,然后将其与string进行比较。因为字符串只是一个随机的单词集合,我该怎么做呢?

输入:asdm

输出:a, mad, sad ....(字典中匹配的任何单词。)

for (int i = 0; i < sowpodsList.size(); i++) {
    for (int j = 0; j < sowpodsList.get(i).length(); j++) {
        if (sowpodsList.get(i).charAt(j) ==   )
            ;
    }
}

4 个答案:

答案 0 :(得分:2)

您可以搜索字典中每个单词的每个字符的数量是否等于输入的字符数。

        ArrayList <String> matches = new ArrayList <String> ();

        // for each word in dict
        for(String word : sowpodsList) {

            // match flag
            Boolean nonMatch = true;

            // for each character of dict word
            for( char chW : word.toCharArray() ) {

                String w = Character.toString(chW);

                // if the count of chW in word is equal to its count in input, 
                // then, they are match
                if ( word.length() - word.replace(w, "").length() !=
                    input.length() - input.replace(w, "").length() ) {
                    nonMatch = false;
                    break;
                }
            }
            if (nonMatch) {
               matches.add( word );
            }
        }

        System.out.println(matches);

示例输出: (我使用的dict文件位于:https://docs.oracle.com/javase/tutorial/collections/interfaces/examples/dictionary.txt

Input: asdm
Matches: [ad, ads, am, as, dam, dams, ma, mad, mads, mas, sad]

答案 1 :(得分:1)

如果我是你,我会改变你存储词典的方式。

鉴于字符串输入中包含随机字母,我在这里所做的就是将字典中的所有单词存储在SortedMap<String, char[]>(确切地说是TreeMap)中,其中keys是字典中的单词,值是此单词 sorted 中的字符。

然后我也会对输入字符串中的字符进行排序并进行排序(伪代码,未经过测试):

public Set<String> getMatchingWords(final String input)
{
    final char[] contents = input.toCharArray();
    Arrays.sort(contents);
    final int inputLength = contents.length;

    final Set<String> matchedWords = new HashSet<>();

    char[] candidate;
    int len;
    int matched;


    for (final Map.Entry<String, char[]> entry: dictionary.entrySet()) {
        candidate = entry.getValue();
        // If the first character of the candidate is greater
        // than the first character of the contents, no need
        // to continue (recall: the dictionary is sorted)
        if (candidate[0] > contents[0])
            break;
        // If the word has a greater length than the input,
        // go for the next word
        len = candidate.length;
        if (len > inputLength)
            continue;
        // Compare character by character
        for (matched = 0; matched < len; matched++)
            if (candidate[matched] != contents[matched])
                break;
        // We only add a match if the number of matched characters
        // is exactly that of the candidate
        if (matched == len)
            matchedWords.add(entry.getKey());
    }

    return matchedWords;
}


private static int commonChars(final char[] input, final char[] candidate)
{
    final int len = Math.min(input.length, candidate.length);
    int ret = 0;
    for (int i = 0; i < len; i++) {
        if (input[i] != candidate[i])
            break;
        ret++;
    }
    return ret;
}

使用trie :这也是可能的;是否实用不过是另一个问题,它取决于字典的大小。

但基本原则是相同的:你需要在你的字典中添加一个排序的字符数组,并逐渐添加到trie中(使用构建器)。

特里节点有三个要素:

  • 一个地图,其中的键是下一个可以匹配的字符集,值是匹配的trie节点;
  • 一组可以在该节点上完全匹配的单词。

如果您愿意,可以将您的trie实施基于this one

答案 2 :(得分:0)

转到TRIE实施。

TRIE提供了搜索大量单词数组的最快方法。

https://en.wikipedia.org/wiki/Trie

您需要做的是将所有单词插入到trie数据结构中。

然后只需要在Trie中调用搜索函数来获取布尔匹配信息。

答案 3 :(得分:-1)

有两种方法可以做到这一点。最好的方法取决于数据结构的相对大小。

如果字典很长且字母列表很短,最好对字典进行排序(如果还没有),然后通过置换字母构建所有可能的单词(删除重复字符)。然后使用字符串比较对每个字母组合进行二进制搜索,以查看它是否是字典中的单词。棘手的部分是确保只在适当的时候使用重复的字母。

如果字母列表很长而字典很短,另一种方法就是简单地计算输入字符串中的字母数:两个a,一个s,一个m等。然后对于每个字典单词,如果字典单词中每个单独字母的数量不超过输入字符串中的单词,该单词有效。

无论哪种方式,都要将找到的所有单词添加到输出数组中。

相关问题