3.3
字符串
3.3.1
Trie(前缀树)
数组(好写)
#include <iostream>
#include <cstring>
using namespace std;
const int maxnode=1e5+10;///最多有多少层
const int sigma_size=26;///字母的话就是26
struct Trie{
int ch[maxnode][sigma_size];///ch[u][0]代表这个结点不存在
int val[maxnode];///结点的权值(相当于标记是否为一个字符串的最后一个元素)
int sz;///结点总数
Tire(){sz=1; memset(ch[0],0,sizeof(ch[0])); }///初始化第一个根结点
int idx(char c){return c-'a';}
//
///插入字符串s,附加信息v(权值)。注意v必须非0,因为0代表“本结点不是单词结点”
void insert(char *s, int v){
int u=0, len=strlen(s);
for(int i=0; i<len; i++){
int c=idx(s[i]);
if(!ch[u][c]){///结点不存在
memset(ch[sz],0,sizeof(ch[sz]));
val[sz]=0;///中间结点的附加信息为0.
ch[u][c]=sz++;///新建结点
}
u=ch[u][c];///往下走。
}
val[u]=v;///最后一个字符的附加信息为v。
}
int find(char *s){
int u=0, len=strlen(s);
for(int i=0; i<len; i++){
int c=idx(s[i]);
if(!ch[u][c])return false;
u=ch[u][c];
}
return val[u];
}
bool del(char *s){
int u=0,len=strlen(s);
for(int i=0; i<len; i++){
int c=idx(s[i]);
if(!ch[u][c])return false;///找不到这个孩子。
u=ch[u][c];
}
if(val[u]==0)return false;///不存在以当前结点结尾的字符串
val[u]=0;///把这一个结点标记为0,表示删去这一个字符串。
return true;
}
};
int main()
{
return 0;
}
指针(没debug过。。。。。误用)
#include <iostream>
#include <cstring>
#include <cstdio>
#define mst(x,a) memset(x,a,sizeof(x))
#define For(i,x,y) for(int i=(x); i<=(y); i++)
using namespace std;
const int sigma_size=26;
struct node{
int num;///记录当前结点,有多少个字符串结尾。
node *next[sigma_size];
node(){
num=0;///记录以该结点结尾的字符数。
mst(next,NULL);///初始化,该结点所有指向儿子的指针。
}
}*root;
int idx(char c){return c-'a';}
void insert(node* u, char*s){
int len=strlen(s);
node *p=u;
for(int i=0; i<len; i++){
int k=idx(s[i]);
if(p->next[k]==NULL)p->next[k]=new node();///当前结点不存在,就new 一个新结点。
p=p->next[k];///指向儿子
}
p->num++;///标记尾结点
}
bool find(node *u, char *s){
int len=strlen(s);
node *p=u;
for(int i=0; i<len; i++){
int k=idx(s[i]);
if(p->next[k]==NULL)return false;///当前结点不存在
p=p->next[k];///指向儿子
}
return p->num;///查看是否有该结点结尾的字符串。
}
bool del(node*u, char *s){
int len=strlen(s);
node *p=u;
for(int i=0; i<len; i++){
int k=idx(s[i]);
if(p->next[k]==NULL)return false;///当前结点不存在
p=p->next[k];
}
if(p->num==0)return false;///不存在以该结点结尾的字符串。
///存在
p->num=0;
return true;
}
void init(){root=new node();}
int main()
{
return 0;
}
eg1 Uva1401–Remember the word
eg2 “strcmp()” Anyone? UVA - 11732
非书本中的eg
1
Phone List POJ - 3630
简单判断一个字符串,是否为其他串的前缀。
2
The XOR Largest Pair LibreOJ - 10050
求n个数里的最大xor对。(01Trie)
3
The xor-longest Path POJ - 3764
题2的升级版(01Trie)
4
Nikitosh 和异或 LibreOJ - 10051
题2的升级版(01Trie)