本题可以先插入,后查询,也可以便插入便查询。我用的是第二种思路。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
struct Trie
{
bool flag;
Trie* pNext[10];
Trie()
{
memset(pNext, NULL, sizeof(pNext));
flag = false;
}
};
Trie* proot;
bool isprefix;
void Insert_SearchTrie(char *str)//边插入边查询,假定x[n]是y[n]的前缀,有两种情况:1,x[n]在y[n]前插入,2,x[n]在y[n]后插入
{
int j;
Trie* p = proot;
for(; *str; str++)
{
j = *str - 48;
if(!p->pNext[j])
p->pNext[j] = new Trie;
if(p->flag)//x[n]在y[n]之前插入
isprefix = true;
p = p->pNext[j];
}
p->flag = true;//当字符串str[n]插入完之后,要在此处把flag标记为true,表示该单词到此为止。
if(isprefix)//如果x[n]在y[n]之前插入,则返回
return;
for (int i = 0; i < 10; ++i)//这个表明x[n]在y[n]之后插入
{
if(p->pNext[i])
{
isprefix = true;
break;
}
}
}
void DeleteTrie(Trie* proot)//删除操作,释放内存,这个一定要有,无论超不超时,要不然程序结束后仍然内存被占用着。
{
Trie* p = proot;
for(int i = 0; i < 10; ++i)
{
if(p->pNext[i])
DeleteTrie(p->pNext[i]);
}
delete proot;
}
int main()
{
int T;
int n;
char op[15];
cin>>T;
while(T--)
{
proot = new Trie;
isprefix = false;
cin>>n;
for (int i = 0; i < n; ++i)
{
cin>>op;
if (!isprefix)
{
Insert_SearchTrie(op);
}
}
if(isprefix)
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
DeleteTrie(proot);
}
return 0;
}