【字典树】hdu 1247 Hat’s Words

http://acm.hdu.edu.cn/showproblem.php?pid=1247

第二道字典树。

先建树,然后对每个词进行查询,若串存在前缀和后缀都属于整棵字典树,则满足题意

/*
   hdu 1247 字典树
   此时,cnt表示以该节点到根节点组成的串的个数,而非前缀的个数(区别上一题)
   注意exactly 2的情况
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<algorithm>
#include<sstream>
#define eps 1e-9
#define pi acos(-1)
#define INF 0x7fffffff
#define inf -INF
#define MM 12900
#define N 50
using namespace std;
typedef long long ll;
const int _max = 5e4 + 10;

struct Trie{
  Trie *next[26];
  int cnt;//从根节点到该节点组成的串为前缀的个数
}*root;

void insert(char *s){
  Trie *p = root,*pnew;
  for(int i = 0; i < strlen(s);++ i){
    int x = s[i]-'a';
    if(p->next[x]==NULL){
       pnew = new Trie;
       pnew->cnt = 0;
       for(int j = 0; j < 26; ++ j)
            pnew->next[j] = NULL;
       p->next[x] = pnew;
    }
    //else p->next[x]->cnt++;
    p=p->next[x];
  }
  p->cnt = 1;
}

int search(char *s){
  if(*s=='\0') return 0;
  Trie *p = root;
  for(;*s!='\0';++s){
    int x = *s - 'a';
    if(p->next[x]==NULL) return 0;
    p=p->next[x];
  }
  if(p->cnt==1)return 1;//exactly 2
  return 0;
}

int judge(char *s){
  Trie *p = root;
  for(;*s!='\0';++s){
    int x = *s - 'a';
    if(p->next[x]){
        p = p->next[x];
        if(p->cnt==1&&search(s+1)) return 1;//关键!
    }
  }
  return 0;
}

void init(){
  root = new Trie;
  root->cnt = 0;
  for (int i = 0;i < 26;i ++)
    root->next[i] = NULL;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
#endif // ONLINE_JUDGE
    char str[_max][20];//假定字符串长度不超20
    init();
    int i = 0;
    while(gets(str[i])){
      insert(str[i]);++i;
    }
    for(int j = 0; j<i;++ j){
        if(judge(str[j])) printf("%s\n",str[j]);
    }
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值