结构特点
Trie字典树常用于判断前缀。这个数据结构中每个节点表示状态,而状态转移由串实现,即状态为节点,字符为边。
这是网上找的图片。
实现
class Trie{
private:
int tot;
int ch[1024][26]; //字典树节点,第一维表示节点编号(不用0,0表示没有下一个节点),第二维表示字符,结果为转移的下一个节点
bool com_str[1024]; //第一维表示节点编号,结果为是否为一个前缀的最后一个节点
public:
Trie()
{
tot = 1;
memset(ch,0,sizeof(ch));
memset(com_str,0,sizeof(com_str));
}
void insert(string s)
{
int len = s.length();
int u = 1;
for(int i = 0;i < len;i++)
{
int c = s[i]-'a';
if(!ch[u][c]) ch[u][c] = ++tot; //如果没有对应字符下一节点,则新建一个
u = ch[u][c];
}
com_str[u]=true; //标记最后一个节点
}
bool hasprefix(string s)
{
int len = s.length();
int u = 1;
bool ret = false;
for(int i = 0;i < len;i++)
{
int c = s[i]-'a';
if(!ch[u][c]) return false; //如果没有对应字符下一节点,则说明没有前缀
u = ch[u][c];
if(com_str[u]) return true; //如果下一节点被标记,则一定有前缀
}
}
bool isprefix(string s)
{
int len = s.length();
int u = 1;
bool ret = false;
for(int i = 0;i < len;i++)
{
int c = s[i]-'a';
if(!ch[u][c]) return false; //如果没有对应字符下一节点,则说明不是前缀
u = ch[u][c];
}
return true; //所有字符都曾出现,说明是前缀
}
};