输入
输入的第一行为一个正整数n,表示词典的大小,其后n行,每一行一个单词(不保证是英文单词,也有可能是火星文单词哦),单词由不超过10个的小写英文字母组成,可能存在相同的单词,此时应将其视作不同的单词。接下来的一行为一个正整数m,表示询问的次数,其后m行,每一行一个字符串,该字符串由不超过10个的小写英文字母组成,表示一个询问。
在20%的数据中n, m<=10,词典的字母表大小<=2.
在60%的数据中n, m<=1000,词典的字母表大小<=5.
在100%的数据中n, m<=100000,词典的字母表大小<=26.
输出
对于每一个询问,输出一个整数Ans,表示词典中以给出的字符串为前缀的单词的个数。
实现方式一:二叉树(左孩子右兄弟)
#include<iostream>
#include<string>
#include<malloc.h>
using namespace std;
struct node{
char c;
int count;
node *next;
node *right;
};
node* creat(void)
{
node *p=(node*)malloc(sizeof(node*));
p->count =0;
p->next =NULL;
p->right =NULL;
p->c ='*';
return p;
}
int main()
{
int m,n,i,j=0,k=0,h=0;
string s;
node *root=creat();
node *tmp;
cin>>m;
while(m--)
{
tmp=root;
cin>>s;
j=0;
while(s[j]!='\0')
{
if(tmp->next ==NULL)
{
tmp->next =creat();
tmp=tmp->next ;
tmp->c =s[j];
tmp->count ++;
}
else if(tmp->next ->c ==s[j])
{
tmp=tmp->next;
tmp->count ++;
}
else if(tmp->next ->right ==NULL)
{
tmp->next ->right =creat();
tmp=tmp->next ->right ;
tmp->c =s[j];
tmp->count ++;
}
else
{
tmp=tmp->next ->right ;
while((tmp->c !=s[j])&&(tmp->right !=NULL))
{
tmp=tmp->right ;
}
if(tmp->c ==s[j])
{
tmp->count ++;
}
else
{
tmp->right =creat();
tmp=tmp->right ;
tmp->c =s[j];
tmp->count ++;
}
}
j++;
}
/*
node *rootp=root;
while(rootp->next !=NULL)
{
rootp=rootp->next ;
cout<<rootp->c;
}
*/
}
cin>>m;
while(m--)
{
tmp=root;
cin>>s;
j=0;
while(s[j]!='\0')
{
//cout<<tmp->c ;
if(tmp->next ==NULL)
{
h=0;
break;
}
else if(tmp->next ->c ==s[j])
{
h=1;
tmp=tmp->next;
}
else if(tmp->next->right==NULL)
{
h=0;
break;
}
else
{
tmp=tmp->next ->right ;
while((tmp->c !=s[j])&&(tmp->right !=NULL))
{
tmp=tmp->right ;
}
if(tmp->c ==s[j])
{
h=1;
}
else
{
h=0;
break;
}
}
j++;
}
if(h==0)
{
cout<<"0"<<endl;
}
else if(h==1)
{
cout<<tmp->count<<endl;
}
}
return 0;
}
实现方法二:二十六叉树
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
const int branch = 26;
struct tnode
{
int n;
tnode* child[branch];
};
long n, m;
char str[35];
char base = 'a';
int len;
tnode* create()
{
tnode* tnew = (tnode*)malloc(sizeof(tnode));
tnew->n = 0;
for(int k=0; k<branch; k++)
tnew->child[k] = NULL;
return tnew;
}
int main()
{
scanf("%ld", &n);
tnode* root = create();
root->n = -1; // flag -1: root
tnode* tmp = NULL;
while(n--)
{
scanf("%s", str);
len = strlen(str);
tmp = root;
for(int i=0; i<len; i++)
{
if(tmp->child[str[i]-base] == NULL)
{
tmp->child[str[i] - base] = create();
}
tmp->child[str[i]-base]->n++;
tmp = tmp->child[str[i] - base];
}
}
scanf("%ld", &m);
while(m--)
{
scanf("%s", str);
tmp = root;
len = strlen(str);
for(int j=0; j<len; j++)
{
tmp = tmp->child[str[j] - base];
// if the predixs never appear
if(tmp == NULL)
break;
}
if(tmp == NULL)
printf("0\n");
else
printf("%d\n", tmp->n);
}
return 0;
}
通过运行对比可以发现使用二叉树的结构比使用二十六叉树省空间,但时间开销较大。