Java 查找字典中给定一串单词的所有单词

Java 查找字典中给定一串单词的所有单词,java,Java,我正在尝试编写一个程序,该程序将使用已从文件加载到数组列表中的词典来查找可以从中构造的所有单词。sowpodsList是存储为arrayList的字典。我想对字典中的每个单词进行迭代,然后将其与字符串进行比较。因为字符串只是单词的随机集合,我该如何实现这一点 输入:asdm 输出:a、mad、sad……(字典中匹配的任何单词。) for(int i=0;i输入长度) 继续; //逐字比较 for(匹配的=0;匹配的

我正在尝试编写一个
程序
,该程序将使用已从
文件
加载到
数组列表
中的词典来查找可以从中构造的所有单词。sowpodsList是存储为
arrayList
的字典。我想对字典中的每个单词进行
迭代
,然后将其与
字符串
进行比较。因为字符串只是单词的随机集合,我该如何实现这一点

输入:
asdm

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

for(int i=0;i
如果字典中每个单词的每个字符的计数等于输入的字符计数,则可以进行搜索

        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);
着手实施

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

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


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

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

for (int i = 0; i < sowpodsList.size(); i++) {
    for (int j = 0; j < sowpodsList.get(i).length(); j++) {
        if (sowpodsList.get(i).charAt(j) ==   )
            ;
    }
}
假设字符串输入中有随机字母,我在这里要做的是将字典中的所有单词存储在
SortedMap
(准确地说是
TreeMap
)中,其中键是字典中的单词,值是这个单词中已排序的字符

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

public Set getMatchingWords(最终字符串输入)
{
final char[]contents=input.toCharArray();
数组。排序(内容);
最终整数输入长度=contents.length;
最终集合matchedWords=新HashSet();
char[]候选人;
内伦;
整数匹配;
for(最终的Map.Entry:dictionary.entrySet()){
candidate=entry.getValue();
//如果候选人的第一个字符大于
//比第一个字符的内容,没有必要
//继续(回忆:字典已排序)
if(候选[0]>内容[0])
打破
//如果单词的长度大于输入的长度,
//下一个单词
len=候选长度;
if(长度>输入长度)
继续;
//逐字比较
for(匹配的=0;匹配的

使用trie:这也是可能的;然而,它是否实用是另一个问题,这取决于词典的大小

for (int i = 0; i < sowpodsList.size(); i++) {
    for (int j = 0; j < sowpodsList.get(i).length(); j++) {
        if (sowpodsList.get(i).charAt(j) ==   )
            ;
    }
}
但基本原理是一样的:你需要在字典中有一个单词的排序字符数组,然后一点一点地添加到trie中(使用构建器)

trie节点将有三个元素:

  • 一个映射,其中键是下一个可以匹配的字符集,值是匹配的trie节点
  • 可以在该节点上精确匹配的一组单词

如果需要,您可以基于trie实现。

有两种方法。最佳方式取决于数据结构的相对大小

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

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


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

您能给出一个您期望的输入和输出示例吗CodeGasmer-input:asdm输出:a、mad、sad。。。。dictionary.fge中匹配的任何单词-我不熟悉实现trie结构。你有什么有用的东西我可以参考。事实上,我误解了这个问题;trie不会有帮助…你能多次使用随机信件集合中的一封信吗?你必须从左到右扫描字母吗?例如,
tac
是否仍然对
cat
有效?是否要查找单词的多种用法?请更具体一点,它不是一串单词,而是一个随机的字符串。例如asdfsdsa。我需要从我的字典文件中提取所有可用的单词。@RunTheJewels我编辑过它。这个概念就像是在字谜中一样。@raymefricsance当你告诉我按字母顺序对初始输入进行排序时,我正在跟随你的思路。input=“hijokmnb”排序输入=“bhijkomn”然后通过比较累积字符串的值来增加。既然字典(sowpods)中的字符串不是按字母顺序排列的,那么这对字典(sowpods)会起什么作用呢?@RunTheJewels我也提到过,你应该按照以下步骤对字典中的每个单词进行排序:
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;
}