【问题标题】:How to Print Out the Words In a Trie With a Vector Given a Particular Prefix如何使用给定特定前缀的向量打印出 Trie 中的单词
【发布时间】:2019-04-08 21:54:27
【问题描述】:

我目前正在从事一个项目,在该项目中,我需要打印出与给定前缀匹配的单词,该前缀由用户使用字符串向量给出,以打印出单词。但是,我在开始时遇到了麻烦,希望你们能给我任何建议。

这是我的意思的一个例子

trie { app, address, add, beg, cow, mice} 中的单词 给定广告的前缀 使用向量打印出包含前缀 ad 的单词: 地址 添加

非常感谢您提供的任何帮助。

【问题讨论】:

  • 我说这取决于你如何实现你的 trie。

标签: c++ vector insert trie


【解决方案1】:

首先,trie 是一棵树。

在 trie 中,所有具有给定前缀(例如 ad)的单词实际上都存储在 trie 的子树中,在搜索前缀 ad 时会访问该子树。
因此,打印 trie 中具有给定前缀的所有单词分两步完成:

  1. 找到与您的前缀对应的节点node
  2. 列出以node为根的子树中的所有单词。

这是一个伪代码:

find_all_words_starting_with(string prefix, trieNode node, int depth){
    if (depth == length(prefix)){
        suffix = empty_string
        print_all_words_with_prefix(prefix, suffix, node)
    } else {
        letter = prefix[depth]
        if (node.hasChild(letter)){
            find_all_words_starting_with(prefix, node.getChild(letter), depth+1)
        } else { // no word with the correct prefix
            return
        }
    }
}

print_all_words_with_prefix(prefix, suffix, node){
    if (node.isCompleteWord){
        print(prefix + suffix)
    }
    for each letter c in the alphabet {
        if (node.hasChild(c)){
            print_all_words_with_prefix(prefix, suffix + c, node.getChild(c))
        }
    }
}

find_all_words_starting_with 完成工作的第一部分。它找到前缀对应的节点,并调用第二个函数print_all_words_with_prefix,它将打印子树中的所有完整单词。

【讨论】:

    【解决方案2】:

    这在很大程度上取决于 trie 的实现,尽管我在下面提供了一个示例 trie。

    每个trie包含三样东西:

    • 一堆树枝
    • 一个根(可能为空)
    • 一个布尔值,表示这个 trie 是否代表一个完整的单词

    基于此,我们可以做一些事情,比如将单词添加到 trie,检查单词是否在 trie 中,并对 trie 中的所有单词应用函数。我提供成员函数来做这些事情。

    #include <memory>
    #include <iterator>
    
    struct WordTrie {
        static int index_from_char(char c) {
            return (unsigned char)c; 
        }
        static int char_from_index(int index) {
            return (char)(unsigned char)index; 
        }
        std::unique_ptr<WordTrie[]> branches; 
        WordTrie* root; 
        bool is_complete_word = false; 
        // Make an empty Trie
        WordTrie() : branches(nullptr), root(nullptr) {}
        // Make a WordTrie with the given root
        WordTrie(WordTrie* root) : branches(nullptr), root(root) {}
    
    
        int get_index_in_root() const {
            WordTrie const* branch_zero = root->branches.get();
            return std::distance(branch_zero, this); 
        }
        void append_char(std::string& s) {
            if(root != nullptr) {
                s += char_from_index(get_index_in_root()); 
            }
        }
        void add_word(char const* str, int length) {
            if(length > 0) {
                char c = *str; 
                if(branches == nullptr) {
                    branches.reset(new WordTrie[256]); 
                    for(int i = 0; i < 256; i++) {
                        branches[i].root = this; 
                    }
                }
                branches[index_from_char(c)].add_word(str + 1, length - 1); 
            } else {
                is_complete_word = true; 
            }
        }
        bool has_word(char const* str, int length) {
            if(length == 0) {
                return is_complete_word; 
            }
            return branches[index_from_char(*str)].has_word(str + 1, length - 1); 
        }
        bool has_word(std::string const& s) {
            return has_word(s.data(), s.size()); 
        }
        template<class F>
        void apply_over_words_in_trie(std::string const& word, F&& func) {
            if(is_complete_word) {
                func(word); 
            }
    
            // Exit if there are no branches
            if(branches == nullptr) return; 
            //Add character to 'word'
            std::string new_word = word + '_';
            for(int i = 0; i < 256; i++) {
                new_word.back() = char_from_index(i); 
                branches[i].apply_over_words_in_trie(new_word, func); 
            }
        }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-06
      • 1970-01-01
      • 2015-02-01
      • 1970-01-01
      • 2017-07-18
      • 1970-01-01
      • 2022-01-21
      • 2017-09-03
      相关资源
      最近更新 更多