1. 程式人生 > 實用技巧 >Hat's Words 字典樹變式

Hat's Words 字典樹變式

題意

  給你若干個字串,要求你找出符合條件的字串並輸出,條件是該字串拆成兩段後,兩段均出現過。

思路

  建字典樹,然後遍歷字元列舉端點,對左右兩段字串在字典樹上進行查詢。若均能找到則該字串為符合題意的字串。

  這題的插入不能每個字元的cnt都++,而要在末尾字元++,因為題意要求是拆分後的字元整體出現,不能僅作為另一個字串的字首。

AC程式碼

#include<iostream>
#include<stdio.h>
#include<cstring>
using namespace std;
const int maxn=5e4+5;
int t,n;
char str[maxn][50]; struct node{ int cnt; struct node *next[26]; node(){ cnt=0; memset(next,0,sizeof(next)); } }; node *root; void buildtrie(char *s){ node *p=root; node *tmp=NULL; int len=strlen(s); for(int i=0;i<len;i++){ if(p->next[s[i]-'a
']==NULL){ tmp=new node; p->next[s[i]-'a']=tmp; } p=p->next[s[i]-'a']; } p->cnt++; } int findtrie(char *s){ node *p=root; int len=strlen(s); for(int i=0;i<len;i++){ if(p->next[s[i]-'a']==NULL){ return 0; } p
=p->next[s[i]-'a']; } return p->cnt; } void del(node *root){ for(int i=0;i<26;i++){ if(root->next[i]) del(root->next[i]); } delete(root); } int main() { root=new node; int k=0; while(~scanf("%s",&str[k])){ buildtrie(str[k]); k++; } for(int i=0;i<k;i++){ int len=strlen(str[i]); for(int j=0;j<len;j++){ char t1[50]={'\0'},t2[50]={'\0'}; strncpy(t1,str[i],j); strncpy(t2,str[i]+j,len-j); if(findtrie(t1)!=0&&findtrie(t2)!=0){ cout<<str[i]<<'\n'; break; } //cout<<str[i]<<t1<<" "<<t2<<" "<<"***\n"; } } return 0; }