#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的更多相关文章

  1. 蒟蒻的trie树专题

    POJ 3630 Phone List: 模板 ///meek #include<bits/stdc++.h> using namespace std; using namespace s ...

  2. 3道入门字典树例题,以及模板【HDU1251/HDU1305/HDU1671】

    HDU1251:http://acm.hdu.edu.cn/showproblem.php?pid=1251 题目大意:求得以该字符串为前缀的数目,注意输入格式就行了. #include<std ...

  3. Trie 字典树,hdu1251

    参考博客:https://www.cnblogs.com/TheRoadToTheGold/p/6290732.html 字典树就是单词树,顺着一条路径到达终止结点就形成一个单词,该单词的前缀包含在这 ...

  4. hdu----(1671)Phone List(Trie带标签)

    Phone List Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  5. HDU1251 统计难题 Trie树

    题目很水,但毕竟是自己第一道的Trie,所以还是发一下吧.Trie的更多的应用慢慢学,AC自动机什么的也慢慢学.... #include<iostream> #include<cst ...

  6. HDU1671 - Phone List(Trie树)

    题目大意 给定一些电话号码,判断是否有电话号码是其他电话号码的前缀 题解 裸Trie树嘛~~~~只需要一个插入过程即可,假设X是Y的前缀,在插入的过程中有两种情况,X在Y之前插入,那么在插入Y的时候经 ...

  7. HDU1251 统计难题(Trie)

    统计难题 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others) Total Subm ...

  8. hdu1251(Trie树)

    传送门:统计难题 分析:Trie树入门题,随便写写练下手感,统计每个节点被多少单词经过就可以了. #include <iostream> #include <cstdio> # ...

  9. [hdu1251]统计难题(trie模板题)

    题意:返回字典中所有以测试串为前缀的字符串总数. 解题关键:trie模板题,由AC自动机的板子稍加改造而来. #include<cstdio> #include<cstring> ...

随机推荐

  1. ecshop后台admin文件夹任意更改名

    为了ecshop网站安全起见或不想泄露后台的路径,那么我们必须修改后台admin文件夹名称. 方法和步骤如下: 把原admin文件夹名改成edait为例来说明 首先,把商城根目录下的admin文件夹重 ...

  2. 【不积跬步,无以致千里】五个常用的Linux监控脚本代码

    为大家提供五个常用Linux监控脚本(查看主机网卡流量.系统状况监控.监控主机的磁盘空间,当使用空间超过90%就通过发mail来发警告.监控CPU和内存的使用情况.全方位监控主机),有需要的朋友不妨看 ...

  3. 我的AndroidStudio设置

    转载:http://stormzhang.com/devtools/2014/11/25/android-studio-tutorial1/ 官方下载有两个地方,均需要FQ. Android Deve ...

  4. Java登陆测试

    package test001; import java.io.BufferedReader; import java.io.FileOutputStream; import java.io.IOEx ...

  5. Android提高21篇之二:SurfaceView的基本使用方法

    上次介绍MediaPlayer的时候稍微介绍了SurfaceView,SurfaceView由于可以直接从内存或者DMA等硬件接口取得图像数据,因此是个非常重要的绘图容器,这次我就用两篇文章来介绍Su ...

  6. pomelo组件..

    1.pomelo会加载lib/components目录下的组件.并设置为属性..和存储在Pomelo.components中..注意这里其实存储的是对象的构造函数.. function load() ...

  7. java_类泛型基本实例

    package ming; public class Apple2<T> { public T info; public Apple2(T info) { this.info = info ...

  8. java_spring_bean的作用域_实例是否为单实例

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  9. 在oc代码中使用swift第三方框架

    swift现在使用越来越多了,一些主流的框架或者效果比较好的demo都陆陆续续使用swift写了.所以,要学会如何在oc的项目中调用swift. 这里主要借助一个桥梁文件,这个桥梁文件一般在你导入sw ...

  10. C语言里的文件函数

    1.File *pf = fopen("文件名","打开方式"); 文件名可以加路径,两个"\\"或者一个"/" 打开方 ...