• hihocoder 1014----Trie树


    hihocoder 1014: Trie树

    原题链接:

    http://hihocoder.com/problemset/problem/1014

    算法分析

    解决该题需要构造一个Trie类,用来对输入的每一个字符串进行统计。
    该Trie类每个实例表示一个Trie树的节点,每个节点有26个“槽”,表示 'a'~'z' 的子节点。并且每个节点有一个计数器 count,用来表示经过该节点的字符串的数量,这样,当查询以某个字符串做前缀的词汇的个数的时候,直接借可以返回结果而无需深入查询。

    C++算法实现如下:

    #include<iostream>
    using namespace std;
    class Trie {
    public:
    	Trie() {
    		count = 0;
    		for (int i = 0; i < 27; i++) {
    			child[i] = 0;
    		}
    	}
    
    	~Trie() {
    		for (int i = 0; i < 27; i++) {
    			if (child[i] != 0) {
    				delete child[i];//递归地调用子节点的析构函数,这样,只要释放了根节点,自然会释放其所有的子节点
    			}
    		}
    	}
    
    	void increse() {
    		count++;
    	}
    
    	Trie* & operator[](int ch) {//获取子节点
    		if (ch >= 'a'&&ch <= 'z') {
    			return child[ch - 'a'];
    		}
    		else {
    			return child[26];
    		}
    	}
    
    	void insert(char * str) {//向字典中插入字符串
    		if (str == 0) {
    			return;
    		}
    		char * p = str;
    		Trie* cur = this, *next;
    		if (*p>='a'&&*p<='z') {
    			increse();
    		}
    		while (*p >= 'a'&& *p <='z') {
    			next = (*cur)[*p];
    			if (next == 0) {
    				next = (*cur)[*p] = new Trie();
    			}
    			next->increse();
    			cur = next;
    			p++;
    		}
    	}
    
    	unsigned int query(char* str) {//查询字典中以该字符串为前缀的词汇的数量
    		if (str == 0||*str=='') {
    			return 0;
    		}
    
    		char* p = str;
    		Trie* cur = this;
    		while (*p != '') {
    			if (*p<'a' || *p>'z') {
    				return 0;
    			}
    			cur = (*cur)[*p];
    			if (cur == 0) {
    				return 0;
    			}
    			p++;
    		}
    		return cur->getCount();
    	}
    	unsigned int getCount() {
    		return count;
    	}
    	
    private:
    	Trie* child[27];
    	unsigned int count;
    };
    
    int main(int argc, char* argv[])
    {
    	Trie root;//根节点本身不代表任何字符
    	int n;
    	char str[11];
    	char* p;
    	cin >> n;
    	cin.getline(str, 11);//输入n之后的换行符还在缓冲区里,要通过cin.getline()去除掉{ 这一  步操作会得到空行 }
    	while (n-- > 0) {
    		cin.getline(str, 11);
    		root.insert(str);
    	}
    	int m;
    	cin >> m;
    	cin.getline(str, 11);//输入m之后的换行符还在缓冲区里,要通过cin.getline()去除掉{ 这一  步操作会得到空行 }
    	while (m-- > 0) {
    		cin.getline(str, 11);
    		cout << root.query(str) << endl;
    	}
    
    	//C++编译器会自动地在main函数退出之前调用所有在栈中构造的类的析构函数,所以 root 的析构 函数会自动调用
    	return 0;
    }
  • 相关阅读:
    记忆点
    数组的操作
    console.log()中的运算与打印事件
    ie9上传后下载json
    mysql使用on duplicate key update批量更新数据
    vue 弹出菜单
    mysql备份脚本
    uniapp+nodejs微信支付小程序版
    mycat初体验
    vscode格式化html标签属性不换行(vetur插件)
  • 原文地址:https://www.cnblogs.com/dongling/p/6637002.html
Copyright © 2020-2023  润新知