字典树(Trie树)

字典树是一种树形结构,优点是利用字符串的公共前缀来节约存储空间。字典树最常用于统计,排序和保存大量的字符串。
字典树一般的操作为两种:
1.将字符串插入到一个集合中。
2.查询一个字符串是否在集合中。
插入操作:
例如要插入字符串“in”。开始时位于根,表示为0号节点,此时设p=0,现在查看p是否有一条标识为i的边连着它的子节点,没有则建立一个新的节点1号节点,此时p=1,将0号节点和1号节点的边标识为i。再往下走看是否又有一条标识为n的边连接着1号节点的子节点,没有则建立一个新的节点2号节点,此时p=2,将1号节点和2号节点的边标识为n,这时字符串“in”就完成了插入,最后将2号节点标识为终点。
在这里插入图片描述
在这里插入图片描述

查询操作:
假如一个字符串从根节点开始往下找,沿着标识着S[1] -> S[2] -> S[3] … -> S[S.len]的边移动,如果有一个字符找不到或者找完后最后的那个节点未被标识为终点则这个字符串不在集合中。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
int t, b[100005][26], flag, idx, x;
bool c[100005];
void insert(char* a)//插入字符串
{
    int t = strlen(a), p = 0;
    for (int i = 0; i < t; i++)
    {
        int x = a[i] - 'a';
        if (!b[p][x])//判断p有无被标识为字符a[i]的边连着他的子节点
            b[p][x] = ++idx;//没有就建立一个新的节点
        p = b[p][x];//有则将该子节点的值赋给p
    }
   c[p] = 1;//将p号节点标识为终点
   return;
}
bool search(char *a)//查询字符串
{
    int t = strlen(a), p = 0, s = 0;
    for (int i = 0; i < t; i++)
    {
        int x = a[i] - 'a';
        if (!b[p][x])//没有找到p标识为a[i]的边有子节点连着
            return false;
        p = b[p][x];
    }
    if (c[p])//判断字符串的最后一个字符在集合中是不是终点
        return true;
    else
        return false;
}
int main() 
{
    cin >> t >> x;
    while (t--)
    {
        char a[30];
        scanf("%s", a);
        insert(a);
    }
    while (x--)
    {
        char a[30];
        scanf("%s", a);
        if (search(a))
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值