• 实现Trie树


    实现Trie树

    class Trie {
    public:
        struct Node {
            Node * son[26];
            bool is_end;
    
            Node() {
                for(int i = 0; i < 26; i ++ ) son[i] = nullptr;
                is_end = false;
            }
        }*root;
        /** Initialize your data structure here. */
        Trie() {
            root = new Node();
        }
        
        /** Inserts a word into the trie. */
        void insert(string word) {
            auto p = root;
            for(auto c : word) {
                int u = c - 'a';
                if(!p->son[u]) p->son[u] = new Node();
                p = p->son[u];
            }
            p->is_end = true;
        }
        
        /** Returns if the word is in the trie. */
        bool search(string word) {
            auto p = root;
            for(auto c : word) {
                int u = c - 'a';
                if(!p->son[u]) return false;
                p = p->son[u];
            }
            return p->is_end;
        }
        
        /** Returns if there is any word in the trie that starts with the given prefix. */
        bool startsWith(string prefix) {
            auto p = root;
            for(auto c : prefix) {
                int u = c - 'a';
                if(!p->son[u]) return false;
                p = p->son[u];
            }
            return true;
        }
    };
    
    /**
     * Your Trie object will be instantiated and called as such:
     * Trie* obj = new Trie();
     * obj->insert(word);
     * bool param_2 = obj->search(word);
     * bool param_3 = obj->startsWith(prefix);
     */
    
    • new方法调用很耗时,在做笔试题时很容易超时,要么一次性将需要的内存开出来,要么用数组模拟指针

    Trie字符串统计

    //用来高效地存储和查找字符串集合地数据结构
    //串的类型不会很多
    #include <iostream>
    
    using namespace std;
    
    const int N = 100010;
    
    int son[N][26], cnt[N], idx; //下标是0的点,既是根节点,又是空节点
    //idx 将该字符串分配到一个树结构中,以下标来记录每一个字符的位置。方便之后的插入和查找。
    char str[N];
    
    void insert(char str[]) {
        int p = 0;
        for(int i = 0; str[i]; i ++ ) {
            int u = str[i] - 'a';
            if(!son[p][u]) son[p][u] = ++ idx;
            p = son[p][u];
        }
        cnt[p] ++ ;
    }
    
    int query(char str[]) {
        int p = 0;
        for(int i = 0; str[i]; i ++ ) {
            int u = str[i] - 'a';
            if(!son[p][u]) return 0;
            p = son[p][u];
        }
        return cnt[p];
    }
    
    int main() {
        int n;
        cin >> n;
        
        while(n -- ) {
            char op[2];  //处理技巧
            scanf("%s%s", op, str);
            if(op[0] == 'I') insert(str);
            else printf("%d
    ", query(str));
        }
        
        return 0;
    }
    

    前缀统计

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 1e6 + 10;
    
    int n, m;
    char str[N];
    
    int son[N][26], cnt[N], idx;
    
    void insert(char *str)  // 插入字符串
    {
        int p = 0;
        for (int i = 0; str[i]; i ++ )
        {
            int u = str[i] - 'a';
            if (!son[p][u]) son[p][u] = ++ idx;
            p = son[p][u];
        }
        cnt[p] ++ ;
    }
    
    int query(char *str)  // 查询有多少个字符串是 T 的前缀
    {
        int p = 0, res = 0;
        for (int i = 0; str[i]; i ++ )
        {
            int u = str[i] - 'a';
            if (!son[p][u]) return res;
            p = son[p][u];
            res += cnt[p];
        }
        return res;
    }
    
    
    int main() {
        scanf("%d%d", &n, &m);
        while (n -- ){
            scanf("%s", str);
            insert(str);
        }
        
        while (m -- ) {
            scanf("%s", str);
            printf("%d
    ", query(str));
        }
        
        return 0;
    }
    

    最大异或对

  • 相关阅读:
    【Nginx】开启 gzip和缓存
    webpack分离css单独打包
    【转】为什么Github没有记录你的Contributions
    Swiper使用遇到的问题
    Jenkins 自动化构建
    Pre标签 自动换行
    Gulp入门教程
    计数排序
    直接插入排序
    等差素数列
  • 原文地址:https://www.cnblogs.com/huhu555/p/14665118.html
Copyright © 2020-2023  润新知