Trie的C++实现及HDU1251,hdu1671
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
using namespace std;
template<int Size>
struct trie_node{ bool terminable; //表示节点为字符串的结尾
int node; //子节点的个数
trie_node *child[Size]; //儿子节点
trie_node():terminable(false), node(0){
memset(child,0,sizeof(child)); //初始化节点
} };
template<int Size,typename Index>
class trie{
public:
//定义类名
typedef trie_node<Size> node_type;
typedef trie_node<Size> *link_type; //构造函数
trie(Index i=Index()):index(i){ } //清空函数,用于析构
void clear(){
clear_node(root);
for(int i=0;i<Size;i++)
root.child[i]=0;
}
//插入
template<typename Iterator>
void insert(Iterator begin,Iterator end){
link_type cur= &root;//当前插入结点为根
while(begin!=end){
if(!cur->child[index[*begin]]){//没有插入过
cur->child[index[*begin]]=new node_type;
cur->node++; //插入后,父亲多了一个儿子
}
cur=cur->child[index[*begin]]; //向下走
begin++; //迭代器往前走!
}
cur->terminable=true; } //重载c风格插入
void insert(const char * str){
insert(str,str+strlen(str));
} //查找
template <typename Iterator>
bool find(Iterator begin,Iterator end){
link_type cur=&root;
while(begin!=end){ if(!cur->child[index[*begin]]) //没有节点啊!!!
return false;
cur=cur->child[index[*begin]]; begin++; }
return cur->terminable; //是否为字符串
} //重载c风格
bool find(const char *str){ return find(str,str+strlen(str));
} //删除字符串
template<typename Iterator>
bool earse (Iterator begin,Iterator end){
bool result;
earse_node(begin,end,root,result);
return result; } //c语言风格
bool erase(char *str){
return earse(str,str+strlen(str)); } template<typename Functor>
void traverse(Functor &execute =Functor()){
visit_node(root,execute); }
private:
//访问结点
template<typename Functor>
void visit_node(node_type cur,Functor &execute){
execute(cur);
for(int i=0;i<Size;i++){//dfs
if(cur.child[i]==0) continue;
visit_node(*cur.child[i],execute); }
} //清空
void clear_node(node_type cur){
for(int i=0;i<Size;i++){
if(cur.child[i]==0)continue; //不存在
clear_node(*cur.child[i]);
delete cur.childe[i];
cur.child[i]=0;
if(--cur.node==0) break; //没有节点了 } } //一边搜索一边删除
template<typename Iterator>
bool earse_node(Iterator begin ,Iterator end,node_type &cur,bool &result){
if(begin==end){
result=cur.terminable;
cur.terminalbe=false;
return cur.node==0; }
//当孩子不存在,结果假,返回假
if(cur.child[index[*begin ]]==0) return !(result=false);
else if(earse_node(begin+1,end,*(cur.child[index[*begin]]),result)){
delete cur.child[index[*begin]];
cur.child[index[*begin]]=0;
if(--cur.node==0&&cur.terminable==false ) return true; }
return false; }
//根
node_type root;
//字符转索引,类似hash
Index index; }; class IndexClass{
public:
int operator[](const char key){
return key%26; //一个映射 } }; int main(){
trie<26,IndexClass> t;
t.insert("tree");
t.insert("tea");
t.insert("act");
t.insert("adv");
t.insert("ate");
if(t.find("tree")){
cout<<"find!";
}
char str[50];
while(scanf("%s",str)!=EOF){
if(t.find(str)==1){
cout<<"find"<<endl;
} }
return 0; }
大部分参考http://blog.csdn.net/luxiaoxun/article/details/7937589
后来用1251裸题测试了一下。
Ac果断高兴啊!
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
using namespace std;
template<int Size>
struct trie_node{ bool terminable; //表示节点为字符串的结尾
int node; //子节点的个数
trie_node *child[Size]; //儿子节点
trie_node():terminable(false), node(0){
memset(child,0,sizeof(child)); //初始化节点
} };
template<int Size,typename Index>
class trie{
public:
//定义类名
typedef trie_node<Size> node_type;
typedef trie_node<Size> *link_type; //构造函数
trie(Index i=Index()):index(i){ } //清空函数,用于析构
void clear(){
clear_node(root);
for(int i=0;i<Size;i++)
root.child[i]=0;
}
//插入
template<typename Iterator>
void insert(Iterator begin,Iterator end){
link_type cur= &root;//当前插入结点为根
while(begin!=end){
if(cur->child[index[*begin]]){//插入过
cur=cur->child[index[*begin]];
++(cur->node); }else{
cur->child[index[*begin]]=new node_type;
++(cur->child[index[*begin]]->node);
cur=cur->child[index[*begin]]; } begin++; //迭代器往前走!
}
cur->terminable=true; } //重载c风格插入
void insert(const char * str){
insert(str,str+strlen(str));
} //查找
template <typename Iterator>
bool find(Iterator begin,Iterator end){
link_type cur=&root;
while(begin!=end){ if(!cur->child[index[*begin]]) //没有节点啊!!!
return false;
cur=cur->child[index[*begin]]; begin++; }
return cur->terminable; //是否为字符串
}
template <typename Iterator>
int findNum(Iterator begin,Iterator end){
link_type cur=&root;
while(begin!=end){ if(!cur->child[index[*begin]]) //没有节点啊!!!
return 0;
cur=cur->child[index[*begin]]; begin++; } return cur->node; //是否为字符串
}
//重载c风格
int findNum(const char *str){ return findNum(str,str+strlen(str));
} //重载c风格
bool find(const char *str){ return find(str,str+strlen(str));
} //删除字符串
template<typename Iterator>
bool earse (Iterator begin,Iterator end){
bool result;
earse_node(begin,end,root,result);
return result; } //c语言风格
bool erase(char *str){
return earse(str,str+strlen(str)); } template<typename Functor>
void traverse(Functor &execute =Functor()){
visit_node(root,execute); }
private:
//访问结点
template<typename Functor>
void visit_node(node_type cur,Functor &execute){
execute(cur);
for(int i=0;i<Size;i++){//dfs
if(cur.child[i]==0) continue;
visit_node(*cur.child[i],execute); }
} //清空
void clear_node(node_type cur){
for(int i=0;i<Size;i++){
if(cur.child[i]==0)continue; //不存在
clear_node(*cur.child[i]);
delete cur.childe[i];
cur.child[i]=0;
if(--cur.node==0) break; //没有节点了 } } //一边搜索一边删除
template<typename Iterator>
bool earse_node(Iterator begin ,Iterator end,node_type &cur,bool &result){
if(begin==end){
result=cur.terminable;
cur.terminalbe=false;
return cur.node==0; }
//当孩子不存在,结果假,返回假
if(cur.child[index[*begin ]]==0) return !(result=false);
else if(earse_node(begin+1,end,*(cur.child[index[*begin]]),result)){
delete cur.child[index[*begin]];
cur.child[index[*begin]]=0;
if(--cur.node==0&&cur.terminable==false ) return true; }
return false; }
//根
node_type root;
//字符转索引,类似hash
Index index; }; class IndexClass{
public:
int operator[](const char key){
return key%26; //一个映射 } }; int main(){
trie<26,IndexClass> t;
char s[11];
//freopen("in.txt","r",stdin); while(gets(s) && s[0])
{
t.insert( s);
} while(gets(s))
{
printf("%d\n", t.findNum(s));
} return 0; }
HDU1671
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
#include<vector>
using namespace std;
#define MAXN 10
template<int Size>
struct trie_node
{ bool terminable; //表示节点为字符串的结尾
int node; //子节点的个数
trie_node *child[Size]; //儿子节点
trie_node():terminable(false), node(0)
{
memset(child,0,sizeof(child)); //初始化节点
} };
template<int Size,typename Index>
class trie
{
public:
//定义类名
typedef trie_node<Size> node_type;
typedef trie_node<Size> *link_type; //构造函数
trie(Index i=Index()):index(i) { } //清空函数,用于析构
void clear()
{
clear_node(root);
for(int i=0; i<Size; i++)
root.child[i]=0;
}
//插入
template<typename Iterator>
void insert(Iterator begin,Iterator end)
{
link_type cur= &root;//当前插入结点为根
while(begin!=end)
{
if(cur->child[index[*begin]]) //插入过
{
cur=cur->child[index[*begin]];
cur->node++; }
else
{
cur->child[index[*begin]]=new node_type;
cur->child[index[*begin]]->node++;
cur=cur->child[index[*begin]]; }
begin++; //迭代器往前走!
}
cur->terminable=true; } //重载c风格插入
void insert(const char * str)
{
insert(str,str+strlen(str));
} //插入与判断
template<typename Iterator>
bool insert2(Iterator begin,Iterator end)
{
link_type cur= &root;//当前插入结点为根 bool flag=0;
while(begin!=end)
{
if(cur->child[index[*begin]]) //插入过
{
if(cur->child[index[*begin]]->terminable==true){ flag=1;
}
cur=cur->child[index[*begin]];
cur->node++; }
else
{
cur->child[index[*begin]]=new node_type;
cur->child[index[*begin]]->node++;
cur=cur->child[index[*begin]]; }
begin++; //迭代器往前走!
}
cur->terminable=true;
return flag; } //重载c风格插入
bool insert2(const char * str)
{
return insert2(str,str+strlen(str));
} //查找
template <typename Iterator>
bool find(Iterator begin,Iterator end)
{
link_type cur=&root;
while(begin!=end)
{ if(!cur->child[index[*begin]]) //没有节点啊!!!
return false;
cur=cur->child[index[*begin]]; begin++; }
return cur->terminable; //是否为字符串
}
//重载c风格
bool find(const char *str)
{ return find(str,str+strlen(str));
} //查找节点数目
template <typename Iterator>
int findNum(Iterator begin,Iterator end)
{
link_type cur=&root;
while(begin!=end)
{ if(!cur->child[index[*begin]]) //没有节点啊!!!
return 0;
cur=cur->child[index[*begin]]; begin++; } return cur->node; //是否为字符串
}
//重载c风格
int findNum(const char *str)
{ return findNum(str,str+strlen(str));
} //查找前缀
template <typename Iterator>
bool findPre(Iterator begin,Iterator end)
{
link_type cur=&root;
while(begin!=end)
{ if(!cur->child[index[*begin]]) //没有节点啊!!!
return false; if(cur->terminable) break;
cur=cur->child[index[*begin]]; begin++; }
return begin!=end; //是否为字符串
} bool findPre(const char *str){
return findPre(str,str+strlen(str)); } //删除字符串
template<typename Iterator>
bool earse (Iterator begin,Iterator end)
{
bool result;
earse_node(begin,end,root,result);
return result; } //c语言风格
bool erase(char *str)
{
return earse(str,str+strlen(str)); } template<typename Functor>
void traverse(Functor &execute =Functor())
{
visit_node(root,execute); }
private:
//访问结点
template<typename Functor>
void visit_node(node_type cur,Functor &execute)
{
execute(cur);
for(int i=0; i<Size; i++) //dfs
{
if(cur.child[i]==0) continue;
visit_node(*cur.child[i],execute); }
} //清空
void clear_node(node_type cur)
{
for(int i=0; i<Size; i++)
{
if(cur.child[i]==0)continue; //不存在
clear_node(*cur.child[i]);
delete cur.child[i];
cur.child[i]=0;
if(--cur.node==0) break; //没有节点了 } } //一边搜索一边删除
template<typename Iterator>
bool earse_node(Iterator begin ,Iterator end,node_type &cur,bool &result)
{
if(begin==end)
{
result=cur.terminable;
cur.terminalbe=false;
return cur.node==0; }
//当孩子不存在,结果假,返回假
if(cur.child[index[*begin ]]==0) return !(result=false);
else if(earse_node(begin+1,end,*(cur.child[index[*begin]]),result))
{
delete cur.child[index[*begin]];
cur.child[index[*begin]]=0;
if(--cur.node==0&&cur.terminable==false ) return true; }
return false; }
//根
node_type root; //字符转索引,类似hash
Index index; }; class IndexClass
{
public:
int operator[](const char key)
{
return key%MAXN; //一个映射 } }; char s[10000][11];
int main()
{
trie<MAXN,IndexClass> t; int T,n,i;
// freopen("in.txt","r",stdin);
scanf("%d",&T); while(T--)
{
scanf("%d",&n); t.clear();
for(i=0;i<n;i++){ scanf("%s",s[i]); t.insert(s[i]); }
for(i=0;i<n;i++){ if(t.findPre(s[i])){ puts("NO");
break;
}
}
if(i==n) puts("YES"); } return 0; }
Trie的C++实现及HDU1251,hdu1671的更多相关文章
- 蒟蒻的trie树专题
POJ 3630 Phone List: 模板 ///meek #include<bits/stdc++.h> using namespace std; using namespace s ...
- 3道入门字典树例题,以及模板【HDU1251/HDU1305/HDU1671】
HDU1251:http://acm.hdu.edu.cn/showproblem.php?pid=1251 题目大意:求得以该字符串为前缀的数目,注意输入格式就行了. #include<std ...
- Trie 字典树,hdu1251
参考博客:https://www.cnblogs.com/TheRoadToTheGold/p/6290732.html 字典树就是单词树,顺着一条路径到达终止结点就形成一个单词,该单词的前缀包含在这 ...
- hdu----(1671)Phone List(Trie带标签)
Phone List Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU1251 统计难题 Trie树
题目很水,但毕竟是自己第一道的Trie,所以还是发一下吧.Trie的更多的应用慢慢学,AC自动机什么的也慢慢学.... #include<iostream> #include<cst ...
- HDU1671 - Phone List(Trie树)
题目大意 给定一些电话号码,判断是否有电话号码是其他电话号码的前缀 题解 裸Trie树嘛~~~~只需要一个插入过程即可,假设X是Y的前缀,在插入的过程中有两种情况,X在Y之前插入,那么在插入Y的时候经 ...
- HDU1251 统计难题(Trie)
统计难题 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others) Total Subm ...
- hdu1251(Trie树)
传送门:统计难题 分析:Trie树入门题,随便写写练下手感,统计每个节点被多少单词经过就可以了. #include <iostream> #include <cstdio> # ...
- [hdu1251]统计难题(trie模板题)
题意:返回字典中所有以测试串为前缀的字符串总数. 解题关键:trie模板题,由AC自动机的板子稍加改造而来. #include<cstdio> #include<cstring> ...
随机推荐
- matlab color_rain colorbar
来自http://www.aos.wisc.edu/~dvimont/matlab/Graphics_Tools/color_rain.html Listing of script color_rai ...
- 教你50招提升ASP.NET性能(三):使用Microsoft的PDBs调试和分析外部的程序集和库
(3)Use Microsoft’s PDBs to debug or profile external assemblies or libraries 招数3: 使用Microsoft的PDBs调试 ...
- ThinkPHP CURD方法盘点:order方法
order方法属于模型的连贯操作方法之一,用于对操作的结果排序. 用法 $Model->where('status=1')->order('id desc')->limit(5)-& ...
- Android 如何修改默认的searchable items。
前言 欢迎大家我分享和推荐好用的代码段~~ 声明 欢迎转载,但请保留文章原始出处: CSDN:http://www.csdn.net ...
- 在Struts2中使用ValueStack、ActionContext、ServletContext、request、session等 .
笔者不知道该用哪个词来形容ValueStack.ActionContext等可以在Struts2中用来存放数据的类.这些类使用的范围不同,得到的方法也不同,下面就来一一介绍. 声明:本文参考Strut ...
- careercup-C和C++ 13.5
13.5 谈谈C语言关键字”volatile”的意义(或重要性)? 解答 关键字volatile的作用是指示编译器,即使代码不对变量做任何改动,该变量的值仍可能被外界修改.操作系统.硬件或其他线程都可 ...
- Apache的rewrite规则详细介绍
Apache的rewrite规则详细介绍 发布日期:2008-09-02 16:16 来源: 作者: 点击:7044 rewrite标志 R[=code](force redirect) 强制外部重定 ...
- mysql控制流程函数
1.case语句 select case 2 when 1 then '男' when 2 then '女' else 'xoap' end as result; 2.if语句 select if(1 ...
- rust haskell
http://www.rust-lang.org <null>
- Unix网络编程(3)——C/S模型几种情况
UNP第五章描述了在客户端和服务器连接建立之后会出现的几种情况,并给出了解决方案,做一个简单的总结. 先给出这个简单的回射C/S程序的模型如下图. 1.客户端和服务器正常终止连接 客户端从标准输入 ...