zoukankan      html  css  js  c++  java
  • POJ 2001 Shortest Prefixes 字典树

    题意非常好理解就不说了。然后这道题事实上不用字典树更简单,可是为了练习trie树就写了一下。1A了哈哈,再对照了一下讨论区的大神代码,发现我还是写复杂了。。。

    思路:

    想到利用字典树。继承字典树原有机制。从底端叶子向上找,每条路径最先找

    到的分叉点再往下(从叶子找上来的这条路)一个字符即为所求(特殊情况,

    假设节点处单词已结束。那么就输出整个单词好了),也就是从上往下找到的

    第一个不是路径重合(has_same_path = true)的情况或者是is_word =

    true的情况,用遍历二叉树的方法遍历整个树得到全部前缀。
    推断has_same_path的情况非常easy,假设当前tmp->next[num]不为空,则

    一定has_same_path
    。至于pos则是为了让答案按顺序输出用的


    代码:


    /*
    poj      2001
    11152K	16MS
    */
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    
    #define MAXN 1005
    
    using namespace std;
    
    struct node
    {
    	node *next[26];
    	bool has_same_path;
    	bool is_word;
    	int pos;
    	node()
    	{
    		memset(next , 0 , sizeof(next));
    		has_same_path = is_word = false;
    		pos = -1;
    	}
    }trie[100005];
    int trie_num;
    
    struct out
    {
    	char s[21];
    	int pos;
    	out()
    	{
    		memset(s , 0 , sizeof(s));
    		pos = -1;
    	}
    }ans[MAXN];
    
    int n = 1,id;
    char str[MAXN][21],tmp_str[21];
    
    bool cmp(out a , out b)
    {
    	return a.pos < b.pos;
    }
    
    void insert(char *s , int pos)//插入单词 
    {
    	int len = strlen(s);
    	node *now = &trie[0];
    	for(int i = 0;i < len;i ++)
    	{
    		int num = s[i] - 'a';
    		if(!now->next[num])
    			now->next[num] = &trie[++trie_num];
    		else
    			now->next[num]->has_same_path = true;
    		now = now->next[num];
    		if(now->pos == -1)
    			now->pos = pos;
    	}
    	now->is_word = true;
    	now->pos = pos;
    }
    
    void cons(node *now , int k)//构造答案 
    {
    	if(!now->has_same_path || now->is_word)
    	{
    		tmp_str[k] = 0;
    		memcpy(ans[++id].s , tmp_str , k);
    		ans[id].pos = now->pos;
    		now->is_word = false;//防止回溯时再次计入
    		if(!now->has_same_path)
    			return ;
    	}
    	for(int i = 0;i < 26;i ++)
    	{
    		if(now->next[i])
    		{
    			tmp_str[k] = i + 'a';
    			cons(now->next[i] , k + 1);
    		}
    	}
    }
    
    int main()
    {
    	while(scanf("%s" , str[n]) != EOF)
    	{
    		insert(str[n] , n);
    		n ++;
    	}
    	n --;
    	trie[0].has_same_path = true;
    	cons(&trie[0] , 0);
    	sort(ans + 1 , ans + n + 1 , cmp);
    	for(int i = 1;i <= n;i ++)
    		printf("%s %s
    ",str[i] , ans[i].s);
    	return 0;
    }

    事实上空间不是必需开那么大。为了省事就乱开了

  • 相关阅读:
    腾讯精品课程
    什么都没有,先空出来!
    Python3-super().__init()__
    Python3-模块
    Python3-单例模式
    Python3-私有化修改
    Python3-私有属性
    Python3-面向对象-魔术方法
    Python3-面向对象-四种方法
    Python3-迭代器
  • 原文地址:https://www.cnblogs.com/lytwajue/p/6719652.html
Copyright © 2011-2022 走看看