Trie树小酌

其实Trie树真的很容易且实用,【上次的博客】因为题目需求变形了挺多的,所以写起来有点乱,这次是hiho coder上的一道典型的练习题,所以写起来也很自然了~
题目链接是:http://hihocoder.com/problemset/problem/1014

输入是一个词典,然后是一堆询问,要求对每个query,输出以它为前缀的单词的数量,典型的Trie树应用。
上代码!
需要注意的是,为什么记录子树要用指针数组,这其实跟list的next指针是差不多的,指针有很多优势,近距离操控内存,复制代价很小(如果节点是大的对象,每次递归向下都需要复制一次,浪费时间),等等原因。

#include <stdio.h>
#include <cstring>
#include <stdlib.h>
#include <vector>
using namespace std;


class Trie {
    vector<Trie*> children;
    int num;
    static const int SIZE = 26;

public:
    Trie(): num(0){}

    void insert(char* str) {
        int len = strlen(str);
        Trie* now = this;
        for (int i = 0; i < len; ++i) {
            int index = char2int(str[i]);
            if (now->children.empty())
                now->children = vector<Trie*>(SIZE, NULL);
            if (now->children[index] == NULL)
                now->children[index] = new Trie();
            now = now->children[index];
            ++now->num;
        }
    }

    int query(char* str) {
        int len = strlen(str);
        Trie* now = this;
        for (int i = 0; i < len; ++i) {
            int index = char2int(str[i]);
            if (now->children.empty() || now->children[index] == NULL)
                return 0;
            now = now->children[index];
        }

        return now->num;
    }

    int char2int(char ch) {
        return ch - 'a';
    }
};

int main() {
    int n, m;
    scanf("%d", &n);
    char buf[15];
    Trie tree;

    // 建立词典
    while (n--) {
        scanf("%s", buf);
        tree.insert(buf);
    }

    // 查询过程
    scanf("%d", &m);
    while (m--) {
        scanf("%s", buf);
        printf("%d\n", tree.query(buf));
    }

    return 0;
}

你可能感兴趣的:(Trie树小酌)