Trie入门--Poj3630 Phone List,查单词,HDU1251 统计前缀,PKU2503 Babelfish

HDU1251 统计前缀

给出很多个字符串(只有小写字母组成)和很多个提问串,统计出以某个提问串为前缀的字符串数量(单词本身也是自己的前缀).
Input
输入n,表示有n个字符串(n<=10000)
接下来n行,每行一个字符串,字符串度不超过10
输入m,表示有m个提问(m<=100)
第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.
Output
对于每个提问,给出以该提问为前缀的字符串的数量.
Sample Input
5
banana
band
bee
absolute
acm
4
ba
b
band
abc
Sample Output
2
3
1
0
HINT

#include<cstring>
#include<iostream>
using namespace std;
int a[100001][26],tot=1,End[100001];
void ins(char *str)
{
    int n=strlen(str),p=1;
    for(int i=0;i<n;i++)
    {
        int l=str[i]-'a';
        if(!a[p][l])a[p][l]=++tot;
        p=a[p][l];
        End[p]++;
    }
}
int find(char *str)
{
    int n=strlen(str),p=1;
    for(int i=0;i<n;i++)
    {
        int l=str[i]-'a';
        p=a[p][l];
        if(!p)return 0;
    }
    return End[p];
}
char str[11];
int main()
{
    int n,m;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",str);
        ins(str);
    }
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%s",str);
        printf("%d
",find(str));
    }
    return 0;
}

  

全国英语四级考试就这样如期到来了,可是小Y依然没有做好充分准备。为了能大学毕业,可怜的小Y准备作弊。
小Y费尽心机,在考试的时候夹带了一本字典进考场。现在的问题是:考试的时候可能有很多单词要查,小Y能不能来得及呢?
Input
第一行一个整数N,表示字典中一共有多少个单词。
接下来每两行表示一个单词,其中:第一行是一个长度≤100的字符串,表示这个单词,全部是小写字母,单词不会重复;第二行是一个整数,表示这个单词在字典中的页码。
接下来一行是一个整数M,表示要查的单词数。
接下来M行,每行一个字符串,表示要查的单词,保证在字典中存在。
N≤10000,M≤10000
Output
M行,每行一个整数,表示第i个单词在字典中的页码。
Sample Input
2
scan
10
word
15
2
scan
word

Sample Output
10
15

#include<cstring>
#include<iostream>
using namespace std;
const int maxn=1e6+10;
int a[maxn][26],tot,End[maxn];
void ins(char *str,int f)
{
    int n=strlen(str),p=1;
    for(int i=0;i<n;i++)
    {
        int l=str[i]-'a';
        if(!a[p][l])a[p][l]=++tot;
        p=a[p][l];
    }
    End[p]=f;
}
int find(char *str)
{
    int n=strlen(str),p=1;
    for(int i=0;i<n;i++)
    {
        int l=str[i]-'a';
        p=a[p][l];
        if(!p)return 0;
    }
    return End[p];
}
char str[110];
int main()
{
    int n,m;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int f;
        scanf("%s%d",str,&f);
        ins(str,f);
    }
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%s",str);
        printf("%d
",find(str));
    }
    return 0;
}

  

PKU2503 Babelfish
You have just moved from Waterloo to a big city. The people here speak an incomprehensible dialect
of a foreign language. Fortunately, you have a dictionary to help you understand them.
我们人类的单词在老鼠的词典里面并不适用,所以我们必须来翻译这些词语。这里有许多组人类的单词在老鼠词典里面的写法是什么样的,之后我们有许多询问,对于每个询问求出每个询问在字典里面对应的单词是什么。
Input
Input consists of up to 100,000 dictionary entries, followed by a blank line, followed by
a message of up to 100,000 words. Each dictionary entry is a line containing an English word
followed by a space and a foreign language word. No foreign word appears more than once in the dictionary.
The message is a sequence of words in the foreign language, one word on each line. Each word in the input
is a sequence of at most 10 lowercase letters.
Output
Output is the message translated to English, one word per line. Foreign words not
in the dictionary should be translated as "eh".
Sample Input
dog ogday
cat atcay
pig igpay
froot ootfray
loops oopslay

atcay
ittenkay
oopslay
Sample Output
cat
eh
loops

#include<bits/stdc++.h>
using namespace std;
char s1[100005][12],s2[100005][12],s[100005];
int sum[350000],son[350000][27],tot;
void insert(char *s,int num)
{
    int p=0;
    for(int i=0;s[i];p=son[p][s[i]-'a'],i++)
        if(!son[p][s[i]-'a']) son[p][s[i]-'a']=++tot;
    sum[p]=num;
}
int answer(char *s)
{
    int p=0;
    for(int i=0;s[i];p=son[p][s[i]-'a'],i++)
        if(!son[p][s[i]-'a']) return 0;
    return sum[p];
}
int main()
{
    int i=1;
    while(1)
    {
        gets(s);
        if(s[0]=='') break;
        sscanf(s,"%s %s",s1[i],s2[i]);
        insert(s2[i],i); //插入第二个单词,并记下它对应的序号 
        i++;
    }
    while(~scanf("%s",s))
    {
        int p=answer(s);
        if(p==0) puts("eh");
        else printf("%s
",s1[p]);//输出对应的第一个单词 
    }
}

  

 Poj Phonelist

有N个数字串,问其中是不是有某个串是另一个串的子串,有输出NO,否则输出YES。
Input
Output
Sample Input
2
3
911
97625999
91125426
5
113
12340
123440
12345
98346
Sample Output
NO
YES

就Trie的插入和查找

//注意此题是找到前缀输出no,否则输出yes 
#include<bits/stdc++.h>
using namespace std;
int n,t,flag,cnt,trie[110001][21];
int ed[110001],vis[110001];
char ch[21];
void up()
{
    flag=0;cnt=0;
    memset(ed,0,sizeof(ed));
    memset(vis,0,sizeof(vis));
    memset(trie,0,sizeof(trie));
}
void find()
{
    int nxt=0,len=strlen(ch+1);
    for(int i=1;i<=len;i++)
    {
        int num=ch[i]-'0';
        if(!trie[nxt][num])
             trie[nxt][num]=++cnt;
        nxt=trie[nxt][num];
        //取出它的下一条边 
        if(vis[nxt]&&i==len)
        //如果这条边已存在,且i==len,则说明找到前缀 
        { 
             flag=1;
             return;
        }
        vis[nxt]=1;
        // 加入这条边到trie中 
        if(ed[nxt])
        //如果这条边被打上结尾标记的话 
           {  
                flag=1;
                return;
           }
    }
    ed[nxt]=1;
    //打上结尾标记 
}
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);up();
        for(int i=1;i<=n;i++)
        {
            scanf("%s",ch+1);
            if(!flag)
               {
                  find();
                  
               }
        }
        if(flag)
             printf("NO
");
        else 
             printf("YES
");
    }
    return 0;
}



#include<cstring>
#include<iostream>
using namespace std;
int a[100010][11],tot,End[100010];
void ins(char *str)
{
    int n=strlen(str),p=0;
    for(int i=0;i<n;i++)
    {
        int l=str[i]-'0';
        if(!a[p][l])a[p][l]=++tot;
        p=a[p][l];
        End[p]++;
    }
}
int find(char *str)
{
    int n=strlen(str),p=0;
    for(int i=0;i<n;i++)
    {
        int l=str[i]-'0';
        p=a[p][l];
        if(!p)return 0;
    }
    return End[p]-1;
    //因为在查找的时候,一定会找到自己,所以要减去1
    //这样才能知道是否存在其它字符串是其子串 
}
char str[10010][11];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        tot=0;
        memset(a,0,sizeof(a));
        memset(str,0,sizeof(str));
        memset(End,0,sizeof(End));
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",str[i]);
            ins(str[i]);
        }
        bool flag=0;
        for(int i=1;i<=n;i++)
            if(find(str[i]))
            {
                flag=1;
                break;
            }
        printf(flag==1?"NO
":"YES
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/cutemush/p/12252741.html