TOJ3097: 单词后缀 (字典树 or map瞎搞)

传送门 (<---可以点击的~)

时间限制(普通/Java):1000MS/3000MS     内存限制:65536KByte

描述

有些英语单词后缀都是一样的,现在我们需要从给定的一堆单词里面找出某个后缀的单词个数。

输入

输入有多组数据。
每组第一行输入n,m,0<=n,m<=100000,
第二行到n+1行:输入单词,每个单词仅有小写英文字母组成,长度不超过10。
第n+2行到n+m+1行,输入要找的单词后缀。

输出

在n个单词里面找出输入单词后缀的单词个数,然后输出。每个数据与数据之间换行。

样例输入

6 3
someone
everyone
outside
inside
somebody
nobody
one
side
body

样例输出

2
2
2

思路:既然是求后缀个数,把字符串倒一倒就变求前缀个数了,然后就是写字典树。这题的话,map瞎搞也是能过的,耗时在800MS左右(感觉还是老老实实字典树吧~)

    拿来练字典树模板的。

字典树代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
char str[10100];
struct note{
    note* nxt[27];
    int sum;//保存出现个数 
    note(){
        sum = 0;
        memset(nxt,0,sizeof(nxt));
    }
}a[200010];
void insert(note *root,char s[]){
    note *p = root;
    int i = 0;
    while(s[i]){
        int j = s[i++] - 'a';
        if(p->nxt[j] ==NULL){
            p->nxt[j] = new note();    
        }
        p = p->nxt[j];
        (p->sum) ++;//在构建的时候直接把当前结点的sum+1 说明出现过后缀 
    }
}
int search(note *root ,char s[]){
    note *p = root;
    int i = 0;
    while(s[i]){
        int j = s[i++]-'a';
        if(p->nxt[j] == NULL)return 0;
        p = p -> nxt[j];
    }
    return p -> sum;
}
int main(){
    int n,m;
    while(~scanf("%d %d",&n,&m)){
        note * root = new note();
        while(n--){
            scanf("%s",str);
            strrev(str);
            insert(root,str); 
        }
        while(m--){
            scanf("%s",str);
            strrev(str);
            printf("%d\n",search(root,str));
        }
    }
    return 0; 
}

map代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<cmath>
#include<stack>
#include<vector>
#include<map>
#include<queue>
#include <sstream>
#define LL long long
using namespace std;
map<string,int>ma;
int main(){
    int n,m;
    string s;
    char str[1010];
    while(~scanf("%d%d",&n,&m)){
        ma.clear();
        while(n--){
            cin>>s;
            reverse(s.begin(),s.end());
            while(s.size()>0){
                ma[s]++;
                s.erase(s.size()-1);
            }
        } 
        while(m--){
            scanf("%s",str);strrev(str);
            printf("%d\n",ma[str]);
        }
    }
}

 

posted on 2018-03-29 12:33  Esquecer  阅读(307)  评论(0编辑  收藏  举报

导航