Trie树入门及训练
什么叫Trie树?
Trie树即字典树。
#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()
{
memset(child,,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=; i<Size; i++)
root.child[i]=;
}
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; } void insert(const char * str) //重载c风格插入
{
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; //是否为字符串
} bool find(const char *str) //重载c风格
{
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;
} bool erase(char *str) //c语言风格
{
return earse(str,str+strlen(str)); } private: void clear_node(node_type cur) //清空
{
for(int i=; i<Size; i++)
{
if(cur.child[i]==)continue; //不存在
clear_node(*cur.child[i]);
delete cur.child[i];
cur.child[i]=;
if(--cur.node==) 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==; }
//当孩子不存在,结果假,返回假
if(cur.child[index[*begin ]]==) return !(result=false);
else if(earse_node(begin+,end,*(cur.child[index[*begin]]),result))
{
delete cur.child[index[*begin]];
cur.child[index[*begin]]=;
if(--cur.node==&&cur.terminable==false ) return true; }
return false; }
//根
node_type root;
//字符转索引,类似hash
Index index; }; class IndexClass
{
public:
int operator[](const char key)
{
return key%; //一个映射 } }; int main()
{
trie<,IndexClass> t; //字母就是26,数字就是10
t.insert("tree"); //插入
t.insert("tea");
t.insert("act");
t.insert("adv");
t.insert("ate");
while(scanf("%s",str)!=EOF)//查找
{
if(t.find(str))
{
cout<<"find"<<endl;
} }
return ;
}
之后,怎么少得了经典的问题呢?
HDU1251(统计难题)
#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()
{
memset(child,,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=; i<Size; i++)
root.child[i]=;
}
//插入
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; } void insert(const char * str) //重载c风格插入
{
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; //是否为字符串
} bool find(const char *str) //重载c风格
{
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 ;
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 earse (Iterator begin,Iterator end) //删除字符串
{
bool result;
earse_node(begin,end,root,result);
return result;
} bool erase(char *str) //c语言风格
{
return earse(str,str+strlen(str)); } private: void clear_node(node_type cur) //清空
{
for(int i=; i<Size; i++)
{
if(cur.child[i]==)continue; //不存在
clear_node(*cur.child[i]);
delete cur.child[i];
cur.child[i]=;
if(--cur.node==) 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==; }
//当孩子不存在,结果假,返回假
if(cur.child[index[*begin ]]==) return !(result=false);
else if(earse_node(begin+,end,*(cur.child[index[*begin]]),result))
{
delete cur.child[index[*begin]];
cur.child[index[*begin]]=;
if(--cur.node==&&cur.terminable==false ) return true; }
return false; }
//根
node_type root;
//字符转索引,类似hash
Index index; }; class IndexClass
{
public:
int operator[](const char key)
{
return key%; //一个映射 } }; int main(){
trie<,IndexClass> t;
char s[]; while(gets(s) && s[])
{
t.insert( s);
} while(gets(s))
{
printf("%d\n", t.findNum(s));
} return ; }
HDU1671
http://acm.hdu.edu.cn/showproblem.php?pid=1671
#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()
{
memset(child,,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=; i<Size; i++)
root.child[i]=;
}
//插入
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=;
while(begin!=end)
{
if(cur->child[index[*begin]]) //插入过
{
if(cur->child[index[*begin]]->terminable==true){ flag=;
}
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 ;
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=; i<Size; i++) //dfs
{
if(cur.child[i]==) continue;
visit_node(*cur.child[i],execute); }
} //清空
void clear_node(node_type cur)
{
for(int i=; i<Size; i++)
{
if(cur.child[i]==)continue; //不存在
clear_node(*cur.child[i]);
delete cur.child[i];
cur.child[i]=;
if(--cur.node==) 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==; }
//当孩子不存在,结果假,返回假
if(cur.child[index[*begin ]]==) return !(result=false);
else if(earse_node(begin+,end,*(cur.child[index[*begin]]),result))
{
delete cur.child[index[*begin]];
cur.child[index[*begin]]=;
if(--cur.node==&&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[][];
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=;i<n;i++){ scanf("%s",s[i]); t.insert(s[i]); }
for(i=;i<n;i++){ if(t.findPre(s[i])){ puts("NO");
break;
}
}
if(i==n) puts("YES"); } return ; }
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
using namespace std;
template<int Size>
struct trie_node{ bool terminable; //???????????
int node; //??????
int cnt;
trie_node *child[Size]; //????
trie_node():terminable(false), node(),cnt(){
memset(child,,sizeof(child)); //?????
} };
int maxN;
char sb[];
char s[];
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=;i<Size;i++)
root.child[i]=;
}
//??
template<typename Iterator>
bool 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;
cur->cnt++;
if(cur->cnt> maxN){
maxN=cur->cnt;
// cout<<maxN;
return true;
}
return false; } //??c????
void insert( char * str){
if(insert(str,str+strlen(str))){
strcpy(sb,str); };
} private: //??
void clear_node(node_type cur){
for(int i=;i<Size;i++){
if(cur.child[i]==)continue; //???
clear_node(*cur.child[i]);
delete cur.child[i];
cur.child[i]=;
if(--cur.node==) break; //????? } } //?
node_type root;
//?????,??hash
Index index; }; class IndexClass{
public:
int operator[](const char key){
return key%; //???? } }; int main(){
trie<,IndexClass> t; //freopen("in.txt","r",stdin);
int n;
while(scanf("%d",&n)&&n)
{ maxN=-;
for(int i=;i<n;i++){
scanf("%s",s); t.insert(s);
// cout<<maxN<<endl;
} printf("%s\n",sb);
t.clear();
} return ; }
HDU1075
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
using namespace std;
char str1[];
char str2[];
char st[]; template<int Size>
struct trie_node
{ bool terminable; //表示节点为字符串的结尾
int node; //子节点的个数
char str[];
trie_node *child[Size]; //儿子节点
trie_node():terminable(false), node()
{
memset(child,,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=; i<Size; i++)
root.child[i]=;
}
//插入
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;
int len=strlen(str1);
for(int i=; i<=len; i++)
cur->str[i]=str1[i]; } //重载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++; }
// printf("%s sb",cur->str);
if(cur->terminable)
{
printf("%s",cur->str);
return true; }
return false; //是否为字符串
} //重载c风格
bool find(const char *str)
{ return find(str,str+strlen(str));
} private: //清空
void clear_node(node_type cur)
{
for(int i=; i<Size; i++)
{
if(cur.child[i]==)continue; //不存在
clear_node(*cur.child[i]);
delete cur.childe[i];
cur.child[i]=;
if(--cur.node==) break; //没有节点了 } } //根
node_type root;
//字符转索引,类似hash
Index index; }; class IndexClass
{
public:
int operator[](const char key)
{
return key%; //一个映射 } }; int main()
{
trie<,IndexClass> t;
scanf("%s",str2) ; while(scanf("%s",str1))
{
if(str1[]=='E')
{ break;
}
scanf("%s",str2);
t.insert(str2);
}
scanf("%s",str2); getchar(); while(gets(st))
{ if(st[]=='E')
{ break;
}
int len=strlen(st);
int bg=;
for(int i=; i<len; i++)
{
if(st[i]>='a'&&st[i]<='z')
{ continue;
}
if(!t.find(st+bg,st+i))
{
for(int j=bg; j<i; j++)
printf("%c",st[j]); };
if(st[i]) printf("%c",st[i]);
bg=i+; } puts(""); } return ; }
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
using namespace std;
char str1[];
char str2[];
char st[]; template<int Size>
struct trie_node
{ bool terminable; //表示节点为字符串的结尾
int node; //子节点的个数
char str[];
trie_node *child[Size]; //儿子节点
trie_node():terminable(false), node()
{
memset(child,,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=; i<Size; i++)
root.child[i]=;
}
//插入
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;
int len=strlen(str1);
for(int i=; i<len; i++)
cur->str[i]=str1[i]; } //重载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++; }
// printf("%s sb",cur->str);
if(cur->terminable)
{
printf("%s",cur->str);
return true; }
return false; //是否为字符串
} //重载c风格
bool find(const char *str)
{ return find(str,str+strlen(str));
} private: //清空
void clear_node(node_type cur)
{
for(int i=; i<Size; i++)
{
if(cur.child[i]==)continue; //不存在
clear_node(*cur.child[i]);
delete cur.childe[i];
cur.child[i]=;
if(--cur.node==) break; //没有节点了 } } //根
node_type root;
//字符转索引,类似hash
Index index; }; class IndexClass
{
public:
int operator[](const char key)
{
return key%; //一个映射 } }; int main()
{
trie<,IndexClass> t;
scanf("%s",str2) ; while(scanf("%s",str1))
{
if(str1[]=='E')
{ break;
}
scanf("%s",str2);
t.insert(str2);
}
scanf("%s",str2); getchar(); while(gets(st))
{ if(st[]=='E')
{ break;
}
int len=strlen(st);
int bg=;
for(int i=; i<len; i++)
{
if(st[i]>='a'&&st[i]<='z')
{ continue;
}
if(!t.find(st+bg,st+i))
{
for(int j=bg; j<i; j++)
printf("%c",st[j]); };
if(st[i]) printf("%c",st[i]);
bg=i+; } puts(""); } return ; }
(差别就在字符串copy 上没有拷贝上'\0'……,也就是st[len])
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
template<int Size>
struct trie_node{ bool terminable; //表示节点为字符串的结尾
int node; //子节点的个数 trie_node *child[Size]; //儿子节点
trie_node():terminable(false), node(){
memset(child,,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=;i<Size;i++)
root.child[i]=;
}
//插入
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]]; } // cout<<*begin;
begin++; //迭代器往前走!
}
cur->terminable=true; // cout<<cur->id<<endl; } //重载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; //我在这里re了无数次…忧桑…… cur=cur->child[index[*begin]]; begin++; }
// cout<<*begin<<" "<<*end<<"sb" <<endl;
return cur->terminable; } //重载c风格
bool find(const char *str){ return find(str,str+strlen(str));
} private: //清空
void clear_node(node_type cur){
for(int i=;i<Size;i++){
if(cur.child[i]==)continue; //不存在
clear_node(*cur.child[i]);
delete cur.childe[i];
cur.child[i]=;
if(--cur.node==) break; //没有节点了 } } //根
node_type root;
//字符转索引,类似hash
Index index; }; class IndexClass{
public:
int operator[](const char key){
return key%; //一个映射 } };
char str[][]; int main(){
trie<,IndexClass> t;
int i=; while(scanf("%s",str[i])!=EOF){
// cout<<str[i];
t.insert(str[i]);
i++;
} for(int j=;j<i;j++){ int len=strlen(str[j]);
for(int p=;p<=len-;p++){ if(t.find(str[j],str[j]+p)){ if(t.find(str[j]+p)){ printf("%s\n",str[j]);
break;
} } } } return ; }
尽管我上面这个做法已经OK了,但是这是参考了别人,下面是我完全按自己想法写的,程序员最高兴的莫过于可以将自己的想法实现。
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
template<int Size>
struct trie_node{ bool terminable; //表示节点为字符串的结尾
int node; //子节点的个数 trie_node *child[Size]; //儿子节点
trie_node():terminable(false), node(){
memset(child,,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=;i<Size;i++)
root.child[i]=;
}
//插入
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]]; } // cout<<*begin;
begin++; //迭代器往前走!
}
cur->terminable=true; // cout<<cur->id<<endl; } //重载c风格插入
void insert(const char * str){
insert(str,str+strlen(str));
} //查找
template <typename Iterator>
bool find(Iterator begin,Iterator end,int i){
link_type cur=&root; while(begin!=end){ if(cur->terminable){
if(i>) return false;
if( find(begin,end,i+))return true;
} if(!cur->child[index[*begin]]) return false;
cur=cur->child[index[*begin]]; begin++; }
if(!cur->terminable){
return false;
}
return i==; } //重载c风格
bool find(const char *str,int i){ return find(str,str+strlen(str),i);
} private: //清空
void clear_node(node_type cur){
for(int i=;i<Size;i++){
if(cur.child[i]==)continue; //不存在
clear_node(*cur.child[i]);
delete cur.child[i];
cur.child[i]=;
if(--cur.node==) break; //没有节点了 } } //根
node_type root;
//字符转索引,类似hash
Index index; }; class IndexClass{
public:
int operator[](const char key){
return key%; //一个映射 } };
char str[][]; int main(){
trie<,IndexClass> t;
int i=;
//freopen("in.txt","r",stdin);
while(scanf("%s",str[i])!=EOF){
// cout<<str[i];
t.insert(str[i]);
i++;
} for(int j=;j<i;j++){ if(t.find(str[j],)){ //类似与dfss printf("%s\n",str[j]);
} } return ; }
HDU1857,逆向思维的trie,可以参考我之前写过的,点这里
http://acm.hdu.edu.cn/showproblem.php?pid=1857
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
template<int Size>
struct trie_node{ bool terminable; //表示节点为字符串的结尾
int node; //子节点的个数
int id;
trie_node *child[Size]; //儿子节点
trie_node():terminable(false), node(){
memset(child,,sizeof(child)); //初始化节点
} };
int RR[],CC[];
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=;i<Size;i++)
root.child[i]=;
}
//插入
template<typename Iterator>
void insert(Iterator begin,Iterator end,int i){ 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;
cur->id=i; } //重载c风格插入
void insert(const char * str,int i){
insert(str,str+strlen(str), i);
} //查找
template <typename Iterator>
void find(Iterator begin,Iterator end,int r,int c){
link_type cur=&root;
while(begin!=end){ if(cur->terminable){ if(RR[cur->id]==){ RR[cur->id]=r;
CC[cur->id]=c;
}
} if(!cur->child[index[*begin]]) //没有节点啊!!!
return ; cur=cur->child[index[*begin]]; begin++; }
if( cur->terminable) {//是否为字符串 if(RR[cur->id]==){ RR[cur->id]=r;
CC[cur->id]=c;
}
} } //重载c风格
void find(const char *str,int r,int c){ find(str,str+strlen(str),r,c);
} private: //清空
void clear_node(node_type cur){
for(int i=;i<Size;i++){
if(cur.child[i]==)continue; //不存在
clear_node(*cur.child[i]);
delete cur.childe[i];
cur.child[i]=;
if(--cur.node==) break; //没有节点了 } } //根
node_type root;
//字符转索引,类似hash
Index index; }; class IndexClass{
public:
int operator[](const char key){
return key%; //一个映射 } };
char cc[][];
char s[];
int mini(int a,int b){
return a>b?b:a;
}
int main(){
trie<,IndexClass> t;
int R,C,i,j,l,ed;
scanf("%d%d",&R,&C);
getchar(); //读掉回车
for( i=;i<R;i++)
{ gets(cc[i]);
} int N=;
while(gets(s)&&s[]!='-'){
if(s[]){
t.insert(s,N); //用每一个要查找的单词构树
N++;
} } for(i=;i<R;i++)
for( j=;j<C;j++){
//向下
memset(s,,sizeof(s));
if(i+<R) ed=;
else ed=R-i;
for(l=;l<ed;l++){
s[l]=cc[i+l][j]; } t.find(s,i+,j+);
//向右
memset(s,,sizeof(s));
if(j+<C) ed=;
else ed=C-j;
for( l=;l<ed;l++){
s[l]=cc[i][j+l]; } t.find(s,i+,j+); //右下
memset(s,,sizeof(s));
if(i+<R&&j+<C) ed=;
else ed=mini(C-j,R-i);
for( l=;l<ed;l++){
s[l]=cc[i+l][j+l]; } t.find(s,i+,j+); } for( i=;i<N;i++){ if(RR[i]!=||CC[i]!=)
printf("%d %d\n",RR[i]-,CC[i]-);
else puts("-1 -1");
} return ; }
Trie树入门及训练的更多相关文章
- Trie树入门
Trie树入门 貌似很多人会认为\(Trie\)是字符串类型,但是这是数据结构!!!. 详情见度娘 下面开始进入正题. PS:本文章所有代码未经编译,有错误还请大家指出. 引入 先来看一个问题 给 ...
- HDOJ1251-统计难题(trie树入门)
统计难题 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others) Total Subm ...
- hdu 1251 统计难题(trie树入门)
统计难题 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others)Total Submi ...
- hdu1251(Trie树)
传送门:统计难题 分析:Trie树入门题,随便写写练下手感,统计每个节点被多少单词经过就可以了. #include <iostream> #include <cstdio> # ...
- HDU1251 统计难题 【trie树】
统计难题 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others) Total Subm ...
- 字典(trie)树--从入门到入土
今天再来认识一个强大的数据结构. 字典树又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词 ...
- 基于trie树的具有联想功能的文本编辑器
之前的软件设计与开发实践课程中,自己构思的大作业题目.做的具有核心功能,但是还欠缺边边角角的小功能和持久化数据结构,先放出来,有机会一点点改.github:https://github.com/chu ...
- trie树--详解
文章作者:yx_th000 文章来源:Cherish_yimi (http://www.cnblogs.com/cherish_yimi/) 转载请注明,谢谢合作.关键词:trie trie树 数据结 ...
- 转:trie树--详解
前几天学习了并查集和trie树,这里总结一下trie. 本文讨论一棵最简单的trie树,基于英文26个字母组成的字符串,讨论插入字符串.判断前缀是否存在.查找字符串等基本操作:至于trie树的删除单个 ...
随机推荐
- C# 制作外挂常用的API
C#做外挂的常用API,本人用了很久,基本没发现问题 using System; using System.Collections.Generic; using System.Text; using ...
- delphi queryCommandState
如何 获取当前光标所在的字符属性 关键点 function queryCommandState(const cmdID: WideString): WordBool; safecall; 粗体 斜体 ...
- webqq 获得好友列表hash算法 获得最新hash的方法
webqq获得好友列表的hash算法,大约每一个月中旬会变动一次.知道怎么获得他就能够了. js文件路径 http://web.qstatic.com/webqqpic/pubapps/0/50/eq ...
- HDU 1080 DP
匹配两个人相似度. A,G,C.T.每两个都会有一个相应的值,给出两串基因.长度能够不一样,能够在基因中间加_使两串长度一样.然后有一个相应值.求最大相应值. 先做出相应的表 DP方程: x=dp[i ...
- HDU 1498 50 years, 50 colors (行列匹配+最小顶点覆盖)
题目:点击打开链接 题意:每个格子有不同颜色的气球用不同数字表示,每次可选某一行 或某一列来戳气球.每个人有K次机会.求最后哪些气球不能在 k次机会内 ...
- iOS开发——网络编程Swift篇&(八)SwiftyJSON详解
SwiftyJSON详解 最近看了一些网络请求的例子,发现Swift在解析JSON数据时特别别扭,总是要写一大堆的downcast(as?)和可选(Optional),看?号都看花了.随后发现了这个库 ...
- C++中栈区 堆区 常量区
原文地址:http://blog.csdn.net/xcyuzhen/article/details/4543264 C++中栈区 堆区 常量区(由一道面试题目而学习) -- : #include&l ...
- 决策树算法实现(train+test,matlab) 转
原文:http://www.zgxue.com/198/1985544.html 华电北风吹 天津大学认知计算与应用重点实验室 修改日期:2015/8/15 决策树是一种特别简单的机器学习分类算法.决 ...
- 从 Auto Layout 的布局算法谈性能
这是使用 ASDK 性能调优系列的第二篇文章,前一篇文章中讲到了如何提升 iOS 应用的渲染性能,你可以点击 这里 了解这部分的内容. http://t.cn/Rc4KbUC 在上一篇文章中,我们提到 ...
- hdfs: 数据流(二)
大部分的HDFS程序对文件操作需要的是一次写多次读取的操作模式. 一个文件一旦创建.写入.关闭之后就不需要修改了.这个假定简单化了数据一致的问题和并使高吞吐量的数据访问变得可能. 1. 读文件 从上图 ...