使用用户输入的字符串找到可以制作的最长单词

时间:2014-03-03 20:06:20

标签: java algorithm search data-structures tree

基本上我想创建一个模拟Channel 4上'Countdown'游戏的程序。实际上用户必须输入9个字母,程序将搜索字典中可以用这些字母制作的最大单词.I认为树结构会更好,而不是哈希表。我已经有一个文件,其中包含字典中的单词,并将使用文件io。

这是我的文件io类:

public static void main(String[] args){
     FileIO reader = new FileIO();
     String[] contents = reader.load("dictionary.txt");
}

这是我目前在Countdown课程中的内容

public static void main(String[] args) throws IOException{
     Scanner scan = new Scanner(System.in);
     letters = scan.NextLine();
}

我从这里完全迷失了。我知道这只是一个开始,但我不是在寻找答案。我只是想要一点点帮助,也许是一个指向正确方向的指针。我只是java的新手,在一本采访书中发现了这个问题,并认为我应该给它一个。

提前致谢

5 个答案:

答案 0 :(得分:0)

欢迎来到Java世界:)

我在那里看到的第一件事就是你有两种主要的方法,你实际上并不需要这样。在大多数情况下,您的程序将只有一个入口点,然后它会完成所有逻辑并处理用户输入和所有内容。

你正在考虑一个很好的树形结构,尽管可能有更好的想法存储它。试试这个:http://en.wikipedia.org/wiki/Trie

您的程序要做的是逐行读取文件中的所有单词,并在此过程中构建数据结构树。完成后,您可以要求用户输入,输入输入后,您可以搜索树。

由于您特意要求不提供答案,我不会在此处提供代码,但随时可以询问您是否对某些内容不清楚

答案 1 :(得分:0)

英语中只有大约800,000个单词,因此一个有效的解决方案是将这800,000个单词存储为800,000个26个1字节整数数组,计算每个字母在单词中的使用次数,然后为输入9个字符,转换为查询的类似26整数计数格式,然后如果查询向量大于或等于单词向量分量,则可以从查询字母形成单词。您可以通过这种方式轻松处理每秒100个查询的顺序。

答案 2 :(得分:0)

我会编写一个以所有双字母单词开头的程序,然后写三个字母的单词,四个字母的单词等等。

当你做两个字母的单词时,你会想要一些方法来挑选第一个字母,然后从剩下的字母中挑选第二个字母。您可能希望对此部分使用递归。最后,你将根据字典检查它。尝试以一种方式编写它,这意味着您可以为三个字母的单词重复使用相同的代码。

答案 3 :(得分:0)

我相信,Regular Expressions的力量会在你的情况下派上用场:

1)创建一个带有符号类的正则表达式字符串,如:/ ^ [abcdefghi] * $ /用你的字母代替“abcdefghi”。

2)使用该正则表达式作为过滤器从文本文件中获取字符串数组。

3)按长度排序。最长的词就是你需要的!

查看Regular Expressions Reference以获取更多信息。

UPD:这是一个很好的Java Regex Tutorial

答案 4 :(得分:0)

第一种方法可能是使用包含词表中所有字母的树。

如果一个节点是单词的结尾,则标记为单词结尾节点。

Tree

在上图中,最长的单词是 banana 。但还有其他一些词,比如 ball ban banal

因此,节点必须具有:

  1. 一个角色
  2. 如果是单词的结尾
  3. 儿童名单。 (最多26)
  4. 插入算法非常简单:在每一步中,我们“剪切”单词的第一个字符,直到该单词不再有字符。

    public class TreeNode {
    
        public char c;
        private boolean isEndOfWord = false;
        private TreeNode[] children = new TreeNode[26];
    
        public TreeNode(char c) {
            this.c = c;
        }
    
        public void put(String s) {
            if (s.isEmpty())
            {
                this.isEndOfWord = true;
                return;
            }
            char first = s.charAt(0);
            int pos = position(first);
            if (this.children[pos] == null)
                this.children[pos] = new TreeNode(first);
    
            this.children[pos].put(s.substring(1));
        }
    
        public String search(char[] letters) {
            String word = "";
            String w = "";
    
            for (int i = 0; i < letters.length; i++)
            {
                TreeNode child = children[position(letters[i])];
                if (child != null)
                    w = child.search(letters);
                   //this is not efficient. It should be optimized.
                if (w.contains("%")
                        && w.substring(0, w.lastIndexOf("%")).length() > word
                                .length())
                    word = w;
            }
                // if a node its end-of-word we add the special char '%'
            return c + (this.isEndOfWord ? "%" : "") + word;
        }
        //if 'a' returns 0, if 'b' returns 1...etc
        public static int position(char c) {
            return ((byte) c) - 97;
        }
    
    
    }
    

    示例:

    public static void main(String[] args) {
        //root
        TreeNode t = new TreeNode('R');
        //for skipping words with "'" in the wordlist
        Pattern p = Pattern.compile(".*\\W+.*");
        int nw = 0;
        try (BufferedReader br = new BufferedReader(new FileReader(
                "files/wordsEn.txt")))
        {
            for (String line; (line = br.readLine()) != null;)
            {
                if (p.matcher(line).find())
                    continue;
                t.put(line);
                nw++;
            }
            // line is not visible here.
            br.close();
            System.out.println("number of words : " + nw);
            String res = null;
            // substring (1) because of the root
            res = t.search("vuetsrcanoli".toCharArray()).substring(1);
            System.out.println(res.replace("%", ""));
        }
    
        catch (Exception e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    
    }
    

    输出:

    number of words : 109563
    counterrevolutionaries
    

    注意: