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树采用了左儿子右兄弟的表示法来节省空间. 假设两个不相等的字符串的最长公 ...
随机推荐
- js 模板引擎 -Art Template
一个例子涵盖所有: <!doctype html> <html> <head> <meta charset="UTF-8"> < ...
- 最长上升子序列(LIS)长度及其数量
例题51Nod-1376,一个经典问题,给出一个序列问该序列的LIS以及LIS的数量. 这里我学习了两种解法,思路和代码都是参考这两位大佬的: https://www.cnblogs.com/reve ...
- java while循环
/* while 循环有一个标准格式,还有一个扩展格式 标准格式: while(条件表达式){ 循环体 } 扩展格式: 初始化语句; while(条件判断){ 循环体 步进表达式 } */ publi ...
- String 字符串和StringBuffer的知识点总结
String字符串 1 字符串.equals(); equals和length的区别:equals ...
- 【串线篇】SpringMvc源码分析
一.DispathcherServlet结构分析 1).所有请求过来DispatcherServlet收到请求, 2).调用doDispatch()方法进行处理 1).getHandler():根据当 ...
- PHP curl_multi_select函数
curl_multi_select — 等待所有cURL批处理中的活动连接 说明 int curl_multi_select ( resource $mh [, float $timeout = 1. ...
- Python基础教程(010)--第一个程序Hello Python
前言 会编写Hello Python源程序 内容 1,在桌面下,新建Python目录 2,在认识的Python目录下,新建一个HelloPython的文件 linux下: touch HellPyth ...
- webpack 导出、导入模块(及路径)
参考:https://blog.csdn.net/xyphf/article/details/83411552 (下面的代码亲测有效) 注:导入的模块的方法,只有两种方法 import 和 requ ...
- [CSP-S模拟测试]:F(DP+线段树)
题目传送门(内部题49) 输入格式 第一行四个整数$n,q,a,b$.接下来$n$行每行一个整数$p_i$. 输出格式 一行一个整数表示答案. 样例 样例输入: 10 3 3 7 样例输出: 数据范围 ...
- Qwidget布局操作之QGridLayout(网格布局)
QMainWindow并没有setLayout()函数,因此不能使用setLayout()函数来设置layout,需要使用间接的方法. 需要做的只是先定义一个QWidget对象,然后使用QMainWi ...