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;
}

猜你喜欢

转载自www.cnblogs.com/qq2210446939/p/13394030.html