前缀树--电话列表问题

电话列表

给出一个电话列表,如果列表中存在其中一个号码是另一个号码的前缀这一情况,那么就称这个电话列表是不兼容的。

假设电话列表如下:

  • Emergency 911
  • Alice 97 625 999
  • Bob 91 12 54 26

在此例中,报警电话号码(911)为 Bob 电话号码(91 12 54 26)的前缀,所以该列表不兼容。

此题需要判断:

1.是否存在一个字符串是当前字符串的前缀--> strlen(当前)> strlen(之前):是否创建当前字符串时发现了结束标志。

2.当前字符串是否是某个字符串的前缀--> strlen(当前)< strlen(之前):是否能够检索到当前字符串-->没有构建新的节点!

#include <bits/stdc++.h>
using namespace std;
int t ,n ,que;//组 个数 序号
char s[11] ;// 存储电话号码
int trie[100010][11] ,js[100010];//前缀树【节点】【号】 记录结束位置
bool insert(char* s)//插入字符串/构建前缀树
{
    int p = 0;
    bool jsl = false ;//1.遍历路径时是否发现了结束标志 0否 {1是}
    bool new_jd = false ;//2.便利路径时是否创建了新的节点 0否 {1是}
    for(int i = 0 ; s[i] ; i ++)
    {
        int ss = s[i] - '0' ;
        if(!trie[p][ss])//没有这个节点,构建节点
        {
            trie[p][ss] = ++ que;
            new_jd = true ;
        }
        p = trie[p][ss] ;
        if(js[p]) jsl = true ;//发现了结束标记(判断1)
    }
    js[p] = true ;//标记当前字符串的结束位置
    return jsl || !new_jd ;
}
int main ()
{
    cin >> t ;
    while(t--)
    {
        cin >> n  ;
        que = 0 ;
        memset(trie,0,sizeof trie) ;//每一组数据要初始化
        memset(js ,0 ,sizeof js) ;
        bool pd = true ;
        for(int i = 0 ; i < n ; i ++)
        {
            cin >> s;
            //不兼容(有前缀):1.发现结束标志--》jsl == 1
            //或者2.没有创建新的节点--》new_jd == 0
            if(insert(s)) pd = false ;//判断是否为有前缀-不兼容
        }
        if(pd) cout << "YES" << endl ;//兼容
        else cout << "NO" << endl ;//不兼容
    }
    return 0;
}

前缀树:init(初始化),insert(插入):前缀树的构建,注意字符串结束要标记,query(查询):查询部分,查询是否有这个字符串。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值