zoukankan      html  css  js  c++  java
  • Trie树模板题 P2016

    Description

    给出n个单词组成的字典(可能由相同的单词),请你完成下列任务:


    任务1、把n个单词去重后按字典序由小到大后输出。


    任务2、给出m个询问,每次询问一个单词是否在字典中存在,如果存在,输出该单词在字典中出现的次数。


    Input

    第一行为n和m.接下来的n行,每行一个单词。中间空一行。  在接下来的m行,每行一个单词,表示一个询问。


    Output

    开始的n行为任务1的输出结果。空一行后输出m行,每行一个整数,表示询问的结果(不存在,则输出0)。


    Hint

    n,m<=50000所有单词由大小写英文字母组成,长度不超过50。


    Solution

    存trie树的过程就已经将字符串去重并且统计次数了。用一个结构体把tree数组存成ch[n],表示这个结点的字符的下一个结点是哪个,end_line标记次数,或者标记是否是一个完整字符,也可以标记是前缀还是完整字符还是不能匹配。输出去重后的单词就是遍历一次trie树,dofind的过程和insert的过程几乎一致,只是有了一个返回值返回出现的次数。


    注意事项:
    1、输出dfs_trie之后还要打一个回车。
    2、由于是单词所以存trie树和dofind的过程要区分大小写。
    3、循环的过程中lenofS要取等。
    4、开的maxm只有52那么如果在dfs_trie的过程中就不能取52因为它会直接跳到end_line然后陷入死循环。所以maxm开成什么53,54这种就能避免这种问题。
    5、maxn要开到50000*50那么大。
    6、噢我还是傻逼。。。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #define maxm 52
    #define maxn 2500005
    using namespace std;
    struct Trie{
    	int ch[maxm];
    	int end_line;
    }tree[maxn];
    char S[maxn],ans[maxn];
    int n,m,newp;
    void insert(){
    	int x=0;int lenofS=strlen(S+1);
    	for(int i=1;i<=lenofS;i++){
    		int y;
    		if(S[i]>='A'&&S[i]<='Z'){
    			y=S[i]-'A';
    		}
    		if(S[i]>='a'&&S[i]<='z'){
    			y=S[i]-'a'+26;
    		}
    		if(tree[x].ch[y]==0){
    			tree[x].ch[y]=++newp;
    		}
    		x=tree[x].ch[y];
    	}
    	tree[x].end_line++;
    }
    char getword(int d){
    	if(d<26)return d+'A';
    	else return d-26+'a';
    }
    void dfs_trie(int s,int l){
    	if(tree[s].end_line){
    		ans[l]=0;
    		printf("%s
    ",ans+1);
    	}
    	for(int i=0;i<52;i++){
    		if(tree[s].ch[i]){
    			ans[l]=getword(i);
    			dfs_trie(tree[s].ch[i],l+1);
    		}
    	}
    }
    int dofind(){
    	int x=0;int lenofS=strlen(S+1);
    	for(int i=1;i<=lenofS;i++){
    		int y;
    		if(S[i]>='A'&&S[i]<='Z'){
    			y=S[i]-'A';
    		}
    		if(S[i]>='a'&&S[i]<='z'){
    			y=S[i]-'a'+26;
    		}
    		if(tree[x].ch[y]==0){
    			return 0;
    		}
    		x=tree[x].ch[y];
    	}
    	return tree[x].end_line;
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++){
    		scanf("%s",S+1);
    		insert();
    	}
    	dfs_trie(0,1);
    	putchar('
    ');
    	for(int i=1;i<=m;i++){
    		scanf("%s",S+1);
    		int o=dofind();
    		printf("%d
    ",o);
    	}
    	return 0;
    }
    
  • 相关阅读:
    java常用容器简要性能分析(List。Map。Set)
    初始化 List 的五种方法(java)【转】
    线程池方式对数组多线程随机取出分析
    Spring文件下载方式整理
    阿里云linux安装Consul启动
    Java字节流&字符流的转换
    VUE中字符串实现JSON格式化展示。
    java中URL作为参数前后端传递分析
    Java实现GBK转码到UTF-8(文件)
    python处理Excel文件
  • 原文地址:https://www.cnblogs.com/virtual-north-Illya/p/10045110.html
Copyright © 2011-2022 走看看