找到字典中最长的单词,以便可以通过连续向前一个单词添加单个字符来构建它

时间:2013-07-18 07:28:01

标签: string dictionary

我找到了以下问题并决定分享其中一种可能的解决方案。

问题:

假设您根据具有固定数量字符的字母给出了单词词典。请编写一个方法/函数,它将在字典中找到最长的单词,以便可以通过连续将单个字符添加到字典中的现有单词(在任何位置)来构建。

例如,“a” - > “at” - > “猫” - > “聊天” - > “图表”。

2 个答案:

答案 0 :(得分:0)

我从这篇文章中提出了解决问题的想法:Successive adding of char to get the longest word in the dictionary

基本上,它迭代字典中的每个单词并通过递归地从字符串中删除字符来生成路径,直到新单词不在字典或大小1中。如果最后一个单词是目标字符,我找到了可能的最大路径。假设字典作为散列映射给出,运行时为O(n * k ^ 2),其中n是字典中的字数,k是最大字符串的长度(最坏情况)。我相信它可以通过修剪一些单词来优化,例如。不包含目标字符的单词。

它返回一组字符串(以简化编码)。对于前者如果目标字符是'a',则此函数返回: [tamped,stamped,ta,a,tape,tap,taped,stampedes,stampede]

我很感激对此解决方案的任何想法。

    public static Set<String> findLongestPath(char targetChar, 
Set<String> dictionary) {

        Set<String> maxPath = new HashSet<String>();

        for (String word: dictionary) {
            Set<String> currentPath = findPath(word, dictionary, targetChar);
            if (maxPath.size() < currentPath.size()) {
                maxPath = currentPath;
            }
        }
        return maxPath;
    }

    public static Set<String> findPath(String word, Set<String> dictionary, char targetChar) {
        String targetCharStr = "" + targetChar;
        Set<String> path = new HashSet<String>();

        if (word.length() == 1) {
            path.add(word);
        } else if (dictionary.contains(word)) {
            for (int i = 0; i < word.length(); i++) {
                //remove one character from a word and try to find path for it
                String subWord = word.substring(0, i) + word.substring(i + 1);
                Set<String> deepPath = findPath(subWord, dictionary, targetChar);
                //stop if path contains word with a single character wich is a target character
                if (deepPath.contains(targetCharStr)) {
                    path.add(word);
                    path.addAll(deepPath);
                    break;
                }
            }
        }
        return path;
    }

public static Set<String> findLongestPath(char targetChar, Set<String> dictionary) { Set<String> maxPath = new HashSet<String>(); for (String word: dictionary) { Set<String> currentPath = findPath(word, dictionary, targetChar); if (maxPath.size() < currentPath.size()) { maxPath = currentPath; } } return maxPath; } public static Set<String> findPath(String word, Set<String> dictionary, char targetChar) { String targetCharStr = "" + targetChar; Set<String> path = new HashSet<String>(); if (word.length() == 1) { path.add(word); } else if (dictionary.contains(word)) { for (int i = 0; i < word.length(); i++) { //remove one character from a word and try to find path for it String subWord = word.substring(0, i) + word.substring(i + 1); Set<String> deepPath = findPath(subWord, dictionary, targetChar); //stop if path contains word with a single character wich is a target character if (deepPath.contains(targetCharStr)) { path.add(word); path.addAll(deepPath); break; } } } return path; }

And here is small driver:

    public static void main(String[] args) throws Exception {

        char targetChar = 'a';
        Set<String> dictionary = new HashSet<String>();
        BufferedReader dictionaryFile = new BufferedReader(new FileReader("/usr/share/dict/words"));
        String line;
        while ((line = dictionaryFile.readLine()) != null) {
            if (line.contains("'")) { continue; }
            dictionary.add(line.toLowerCase().trim());
        }
        dictionaryFile.close();

        System.out.println(findLongestPath(targetChar, dictionary));    
    }

答案 1 :(得分:0)

这是动态编程的一个很好的例子。我将研究本书的动态编程部分http://www.cs.berkeley.edu/~vazirani/algorithms/all.pdf。他从非常简单的例子开始,以一种非常有意义的方式构建复杂的例子。

DP面临的挑战是构建在多项式时间内运行的解决方案。大多数DP解决方案都是O(n ^ 2),它仍然比指数更好(例如在字典中尝试每个组合)。该解决方案将涉及使用数组来构建信息,这些信息将继续构建在自身上并导致具有答案的内容