Phone List
Description:
给定n个字符串,问当中是否有字符串是其他字符串的前缀。
思路1:
对于每个字符串,判断它的每一个字符(除去最后一个字符)是否是其他字符串的结尾。
思路2;
对于每个子串的结尾,判断它是否是其他字符串的中间字符。
思路1:
#include<stdio.h>
#include<iostream>
#include<cmath>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#define ms0(a) memset(a,0,sizeof(a))
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxnode = 1e5+5;
int trie[maxnode][11],tot=0,strend[maxnode];
char dir[maxnode][15];
void insert(char* str)
{
int len =(int)strlen(str),p=0;
for(int k=0;k<len;k++)
{
int ch = str[k]-'0';
if(trie[p][ch]==0)
{
trie[p][ch] = ++tot;
}
p = trie[p][ch];
}
strend[p]++;
}
bool search(char* str)
{
int len = (int)strlen(str),p=0;
for(int k=0;k<len-1;k++)
{
p = trie[p][str[k]-'0'];
if(strend[p])
return false;
}
return true;
}
int main(){
int ncase,n;
cin>>ncase;
while (ncase--)
{
scanf("%d",&n);
ms0(trie);ms0(strend);
tot=0;
for(int i=1;i<=n;i++)
{
scanf("%s",dir[i]);
insert(dir[i]);
}
bool flag = true;
for(int i=1;i<=n;i++)
{
if(!search(dir[i]))
{
flag = false;
break;
}
}
if(flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
思路2:
#include<stdio.h>
#include<iostream>
#include<cmath>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#define ms0(a) memset(a,0,sizeof(a))
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxnode = 1e5+5;
int trie[maxnode][11],value[maxnode],tot=0;
char dir[maxnode][15];
void insert(char* str)
{
int len =(int)strlen(str),p=0;
for(int k=0;k<len;k++)
{
int ch = str[k]-'0';
if(trie[p][ch]==0)
{
trie[p][ch] = ++tot;
}
p = trie[p][ch];
value[p]++;
}
}
int search(char* str)
{
int len = (int)strlen(str),p=0;
for(int k=0;k<len;k++)
{
p = trie[p][str[k]-'0'];
}
return value[p]-1;
}
int main(){
int ncase,n;
cin>>ncase;
while (ncase--)
{
scanf("%d",&n);
ms0(trie);ms0(value);
tot=0;
for(int i=1;i<=n;i++)
{
scanf("%s",dir[i]);
insert(dir[i]);
}
bool flag = true;
for(int i=1;i<=n;i++)
{
if(search(dir[i]))
{
flag = false;
break;
}
}
if(flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
前缀统计
Description:
给定n个字符串(可能有相同的),接下来进行M次询问,每次询问给定字符串T,求这n个字符串中有多少个字符串是T的前缀。
字符串的根节点不能只记录一个true或false,还应该记录次数,
查询的时候将经过的根节点的权值累加即可。
int trie[maxnode][11],tot=0,strend[maxnode];
void insert(char* str)
{
int len =(int)strlen(str),p=0;
for(int k=0;k<len;k++)
{
int ch = str[k]-'0';
if(trie[p][ch]==0)
{
trie[p][ch] = ++tot;
}
p = trie[p][ch];
}
strend[p]++;
}
int search(char* str)
{
int len = (int)strlen(str),p=0;
int ans = 0;
for(int k=0;k<len;k++)
{
p = trie[p][str[k]-'0'];
ans += strend[p];
}
return ans;
}