tire 树入门
模板:
前缀是否出现:
/*
trie tree的储存方式:将字母储存在边上,边的节点连接与它相连的字母
trie[rt][x]=tot:rt是上个节点编号,x是字母,tot是下个节点编号
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define maxn 2000010
using namespace std;
int tot=,n;
int trie[maxn][];
//bool isw[maxn];查询整个单词用
void insert(char *s,int rt)
{
for(int i=;s[i];i++)
{
int x=s[i]-'a';
if(trie[rt][x]==)//现在插入的字母在之前同一节点处未出现过
{
trie[rt][x]=++tot;//字母插入一个新的位置,否则不做处理
}
rt=trie[rt][x];//为下个字母的插入做准备
}
/*isw[rt]=true;标志该单词末位字母的尾结点,在查询整个单词时用到*/
}
bool find(char *s,int rt)
{
for(int i=;s[i];i++)
{
int x=s[i]-'a';
if(trie[rt][x]==)return false;//以rt为头结点的x字母不存在,返回0
rt=trie[rt][x];//为查询下个字母做准备
}
return true;
//查询整个单词时,应该return isw[rt]
}
char s[];
int main()
{
tot=;
int rt=;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
cin>>s;
insert(s,rt);
}
scanf("%d",&n);
for(int i=;i<=n;i++)
{
cin>>s;
if(find(s,rt))printf("YES\n");
else printf("NO\n");
}
return ;
} 数组模拟
前缀出现的次数:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int trie[][],len,root,tot,sum[];
bool p;
int n,m;
char s[];
void insert()
{
len=strlen(s);
root=;
for(int i=;i<len;i++)
{
int id=s[i]-'a';
if(!trie[root][id]) trie[root][id]=++tot;
sum[trie[root][id]]++;//前缀后移一个位置保存
root=trie[root][id];
}
}
int search()
{
root=;
len=strlen(s);
for(int i=;i<len;i++)
{
int id=s[i]-'a';
if(!trie[root][id]) return ;
root=trie[root][id];
}//root经过此循环后变成前缀最后一个字母所在位置的后一个位置
return sum[root];//因为前缀后移了一个保存,所以此时的sum[root]就是要求的前缀出现的次数
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
cin>>s;
insert();
}
scanf("%d",&m);
for(int i=;i<=m;i++)
{
cin>>s;
printf("%d\n",search());
}
} 数组模拟
模板题:hdu 1252
前缀出现的次数:
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<string>
using namespace std;
const int max_=1e6+;
int trie[max_][];
int tot=;
char s[max_];
int sum[max_];
void insert(char str[])
{
//int len=str.size();
int rt=;
for(int i=;str[i];i++)
{
int k=str[i]-'a';
if(!trie[rt][k])
trie[rt][k]=++tot;
sum[trie[rt][k]]++;
rt=trie[rt][k];
}
}
int find(char str[])
{
//int len=strlen(str);
int rt=;
for(int i=;str[i];i++)
{
int k=str[i]-'a';
if(!trie[rt][k])
return ;
rt=trie[rt][k];
}
return sum[rt];
}
int main()
{
/*std::ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);*/
//string str;
while(gets(s))
{
//cout<<str<<endl;
if(s[]=='\0')
break;
insert(s);
}
while(scanf("%s",s)!=EOF)
{
// printf("ok\n");
int ant=find(s);
printf("%d\n",ant);
}
}
一句话有多少个单词:hdu 2072
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<sstream>
using namespace std;
const int max_=2e4+;
int tot;
int trie[max_][];
bool book[max_];
void insert(string str)
{
int len=str.size();
int rt=;
for(int i=;i<len;i++)
{
int k=str[i]-'a';
if(!trie[rt][k])
trie[rt][k]=++tot;
rt=trie[rt][k];
}
book[rt]=;
}
bool find_(string str)
{
int len=str.size();
int rt=;
for(int i=;i<len;i++)
{
int k=str[i]-'a';
if(!trie[rt][k])
return ;
rt=trie[rt][k];
}
if(book[rt])
return ;
else
return ;
}
int main()
{
ios::sync_with_stdio(false);
string str1,str2;
while(getline(cin,str1))
{
if(str1=="#")
break;
tot=;
int ant=;
memset(trie,,sizeof(trie));
memset(book,,sizeof(book));
stringstream ss(str1);
while(ss>>str2)
{
//cout<<ss<<endl;
if(!find_(str2))
{
ant++;
insert(str2);
}
}
printf("%d\n",ant);
}
}
tire 树入门的更多相关文章
- Tire树入门专题
POJ 3630Phone List 题目连接:http://poj.org/problem?id=3630 题意:问是否有号码是其他号码的前缀. #include<iostream> # ...
- Trie树入门
Trie树入门 貌似很多人会认为\(Trie\)是字符串类型,但是这是数据结构!!!. 详情见度娘 下面开始进入正题. PS:本文章所有代码未经编译,有错误还请大家指出. 引入 先来看一个问题 给 ...
- 主席树入门(区间第k大)
主席树入门 时隔5个月,我又来填主席树的坑了,现在才发现学算法真的要懂了之后,再自己调试,慢慢写出来,如果不懂,就只会按照代码敲,是不会有任何提升的,都不如不照着敲. 所以搞算法一定要弄清原理,和代码 ...
- poj 3841 Double Queue (AVL树入门)
/****************************************************************** 题目: Double Queue(poj 3481) 链接: h ...
- Codeforces 714C. Sonya and Queries Tire树
C. Sonya and Queries time limit per test:1 second memory limit per test: 256 megabytes input:standar ...
- 中文分词系列(二) 基于双数组Tire树的AC自动机
秉着能偷懒就偷懒的精神,关于AC自动机本来不想看的,但是HanLp的源码中用户自定义词典的识别是用的AC自动机实现的.唉-没办法,还是看看吧 AC自动机理论 Aho Corasick自动机,简称AC自 ...
- 中文分词系列(一) 双数组Tire树(DART)详解
1 双数组Tire树简介 双数组Tire树是Tire树的升级版,Tire取自英文Retrieval中的一部分,即检索树,又称作字典树或者键树.下面简单介绍一下Tire树. 1.1 Tire树 Trie ...
- [数据结构]字典树(Tire树)
概述: Trie是个简单但实用的数据结构,是一种树形结构,是一种哈希树的变种,相邻节点间的边代表一个字符,这样树的每条分支代表一则子串,而树的叶节点则代表完整的字符串.和普通树不同的地方是,相同的字符 ...
- UVa 11732 (Tire树) "strcmp()" Anyone?
这道题也是卡了挺久的. 给出一个字符串比较的算法,有n个字符串两两比较一次,问一共会有多少次比较. 因为节点会很多,所以Tire树采用了左儿子右兄弟的表示法来节省空间. 假设两个不相等的字符串的最长公 ...
随机推荐
- leetcode.图.785判断二分图-Java
1. 具体题目 给定一个无向图graph,当这个图为二分图时返回true.如果我们能将一个图的节点集合分割成两个独立的子集A和B,并使图中的每一条边的两个节点一个来自A集合,一个来自B集合,我们就将这 ...
- Python字符串前缀
1,r/R表示raw string(原始字符串) #!/usr/bin/python str1 = 'hello \n world' str2 = r'hello \n world' print(st ...
- k8s 组件介绍-API Server
API Server简介 k8s API Server提供了k8s各类资源对象(pod,RC,Service等)的增删改查及watch等HTTP Rest接口,是整个系统的数据总线和数据中心. kub ...
- vue - blog开发学习5
基本功能和后台联调 1.首页的所有博客 因为是前后台都是本地开发,所以前端vue需要设置proxy:修改/config/index.js中的这个proxyTable proxyTable: { '/a ...
- [Java 教程 04] Java基础语法
在上一篇文章中我们已经运行了个简单的java程序,但是没有给大家讲解代码部分的内容与含义.学习,我们要做到知其然而知其所以然,所以本篇文章我们就来讲解java程序的基本语法,学完这篇文章你再回头看上篇 ...
- 【知识强化】第四章 网络层 4.5 IPv6
这节课我们来学习一下IPv6. 首先呢我们来看一下为什么会有IPv6的产生.由于我们之前探讨过,对于IPv4这种编址方式呢,这个地址线已经被消耗殆尽了,已经没有剩多少地址.所以我们就学习了两种技术,一 ...
- Codeforces 1178F DP
题意:有一张白纸条,你需要给这张纸条染色.染色从颜色1开始染色,每次选择纸条的一段染色时,这一段的颜色必须是相同的.现在给你染色后的纸条,问有多少种染色方案? F1: 思路:最开始的想法是以染色顺序为 ...
- element el-table 合计在横拉滚动条的下面,正确展示应该是滚动条在合计下面
<style lang="less"> .el-table{ overflow: auto; } .el-table .el-table__body-wrapper, ...
- shell脚本学习(2)查找
1 grep 用法: grep -F fa 找含有fa字符的字符串 yuyuyu@ubuntu:~$ grep -F fa < do.txt grep -i fa 忽略大 ...
- [CSP-S模拟测试]:E(贪心)
题目传送门(内部题48) 输入格式 第一行一个整数$n$.接下来$n$行每行两个整数$x_i,y_i$. 输出格式 一行一个整数表示答案. 样例 样例输入$1$: 23 72 5 样例输出$1$: 样 ...