简单的字典树实现——hiho一下第二周

Problem:

hiho一下第二周:题目1 : Trie树
http://hihocoder.com/contest/hiho2/problem/1
题目要求先建立字典树,然后实现查找拥有指定字符串前缀的所有单词的数量。

Answer:

建立了一颗26叉树,每个子节点代表一个字母,在树的生成过程同时进行统计,加快查找速度。

代码实现:

1.树节点类:

class trienode{  
public:
    char word;  //保存节点的字母,在本题解中无具体作用
    int childnum=0;  //用于统计
    trienode* child[26];  //26个子节点
    trienode(){  //初始化,将所有子节点指向NULL
        for (int i = 0; i < 26; i++){
            child[i] = NULL;
        }
    }
};

2.树类

class trie{
private:
    trienode* root;
    trienode* move;  //用于在字典树上移动的trienode指针
public:
    trie(){
        root = new trienode();
        move = root;
    }
    void insert(string a){
        int len = a.length();
        move = root;
        for (int i = 0; i < len; i++){
            int k = a[i] - 'a';  //得到该字符对应的子节点,提高插入效率
            if (move->child[k] == NULL){  //子节点没有存储该字符
                move->child[k] = new trienode();
                move = move->child[k];
                move->word = a[i];
                move->childnum++;

            }
            else{  //子节点有该字符
                    move = move->child[k];
                    move->childnum++;
            }
        }
    }
    int search(string a){
        int len = a.length();
        move = root;
        for (int i = 0; i < len; i++){
            int k = a[i] - 'a';
            if (move->child[k] == NULL){ return 0; }  //该节点不存在子节点,所以查找结果为0;
            if (i == len - 1){ return move->child[k]->childnum; }  //查找结束,返回结果
            else{
                move = move->child[k];
            }
        }
    }
};

完整题解代码:

#include<iostream>
#include<string>
using namespace std;

class trienode{
public:
    char word;
    int childnum=0;
    trienode* child[26];
    trienode(){
        for (int i = 0; i < 26; i++){
            child[i] = NULL;
        }
    }
};

class trie{
private:
    trienode* root;
    trienode* move;
public:
    trie(){
        root = new trienode();
        move = root;
    }
    void insert(string a){
        int len = a.length();
        move = root;
        for (int i = 0; i < len; i++){
            int k = a[i] - 'a';
            if (move->child[k] == NULL){
                move->child[k] = new trienode();
                move = move->child[k];
                move->word = a[i];
                move->childnum++;

            }
            else{
                    move = move->child[k];
                    move->childnum++;
            }
        }
    }
    int search(string a){
        int len = a.length();
        move = root;
        for (int i = 0; i < len; i++){
            int k = a[i] - 'a';
            if (move->child[k] == NULL){ return 0; }
            if (i == len - 1){ return move->child[k]->childnum; }
            else{
                move = move->child[k];
            }
        }
    }
};

int main(){
    trie Tree;
    int cinnum;
    cin >> cinnum;
    cin.get();

    string* z = new string[cinnum];
    for (int i = 0; i < cinnum; i++){
        getline(cin, z[i]);
        Tree.insert(z[i]);
    }
    int searchnum;

    cin >> searchnum;
    cin.get();

    string a;
    for (int i = 0; i < searchnum; i++){
        getline(cin, a);
        cout<<Tree.search(a)<<endl;
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值