• poj 4052 简单题


    题意     就是给你N 个单词   和 一篇文章;然后问你  在这篇文章里面有多少个 出现的单词;如果一个单词是一个单词的字串,则只能算一个;

    方法    首先用最简单的方法  把字符串解码,然后用模板跑一遍,找到所有单词,然后再用着写被标记的单词  插入字典树,把一路上的字符全部标记;

    #include<iostream>
    #include<stdio.h>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    char cha[2550][1123],str[5123456],sss[5123456];
    bool vis[2550];
    
    structdate
    {
        date *next[26],*fail;
        int tab;
        bool flag;
    }tree[3123456],*que[3123456],*root;
    
    int tail,head,ptr,N;
    
    date *creat_node(  )
    {
        for( int i = 0; i < 26; i++ )
        tree[ptr].next[i] = NULL;
        tree[ptr].fail = NULL;
        tree[ptr].tab = 0;
        tree[ptr].flag = false;
        return &tree[ptr++];
    }
    
    void inint( )
    {
        tail = head = ptr = 0;
        root = creat_node( );
        root->fail = root;
    }
    
    void insert( char *word,int i )
    {
        date *temp = root;
        while( *word )
        {
            int num = *word - 'A';
            if( temp->next[num] == NULL )
                temp->next[num] = creat_node(  );
            temp = temp->next[num];
            word++;
        }
        temp->tab = i;
    }
    
    void build_AC( )
    {
        que[tail++] = root;
        while( tail > head )
        {
            date *temp = que[head++];
            for( int i = 0; i < 26; i++ )
            if( temp->next[i] != NULL )
            {
                if( temp == root ) temp->next[i]->fail = root;
                else               temp->next[i]->fail = temp->fail->next[i];
                temp->next[i]->flag = true;
                que[tail++] = temp->next[i];
            }
            else
            {
                if( temp == root ) temp->next[i] = root;
                else               temp->next[i] = temp->fail->next[i];
            }
        }
    }
    
    int query( char *word )
    {
        date *patten,*temp = root;
        while( *word )
        {
            int num = *word - 'A';
            temp = temp->next[num];
            patten = temp->fail;
            vis[temp->tab] = true;
            while( patten != root )
            {
                if( patten->flag )
                {
                        patten->flag = false;
                    vis[patten->tab] = false;
                }
                else break;
                patten = patten->fail;
            }
            word++;
        }
        for( int i = 1; i <= N; i++ )
        {
            if( vis[i] )
            {
                date *temp = root;
                int k = 0;
                int len = strlen(cha[i]) - 1;
                while( len-- )
                {
                    int num = cha[i][k++] - 'A';
                    temp = temp->next[num];
                    int t   = temp->tab;
                    if( vis[t] )vis[t] = false;
                }
            }
        }
        int ans = 0;
        for( int i = 1; i <= N; i++ )
        if( vis[i] )ans++;
        return ans;
    }
    
    int deal( char *word,int t,int x)
    {
        bool fell = false;
        int len = strlen(word),num = 0,k = 0;
        for( int i = 0; i < len; i++ )
        {
            if( fell )
            {
                if( word[i] - '0' >= 0 && word[i] - '0' <= 9 )
                    num = num*10 +  ( word[i] - '0' );
                else
                {
                    while( num-- )sss[k++] = word[i];
                    fell = false;
                }
                    continue;
            }
            if( word[i] == '[' )
            {
                fell = true; num = 0; continue;
            }
            if( (word[i] - 'A') >= 0 && (word[i] - 'A') <= 25 )
                sss[k++] = word[i];
        }
        sss[k] = '\0';
        if( x )
        {
            for( int i = 0; i < k; i++ )
            cha[t][i] = sss[i];
            cha[t][k] = '\0';
        }
        else
        {
            for( int i = 0; i < k; i++ )
            str[i] = sss[i];
            str[k] = '\0';
        }
        return 0;
    }
    int main( )
    {
        int T,i,j;
        scanf("%d",&T);
        while( T-- )
        {
             scanf("%d",&N); inint( );
             for( i = 1; i <= N; i++ )
             {
                 scanf( "%s",&cha[i] );
                 deal(cha[i],i,1);
                 insert( cha[i],i );
             }
             build_AC( );
             scanf("%s",&str);
             deal(str,0,0);
             memset( vis,false,sizeof(vis) );
             printf("%d\n",query( sss ));
        }
        return 0;
    }
    
  • 相关阅读:
    C#--带参SQL语句数通用数据访问类
    VS 2017产品密匙
    关于编码中的字符和字节问题
    关于C++中的cin用法
    C++基础(一、基本语法,Hello World)
    Oracle查看用户所在的表空间
    静态变量、枚举、以及静态代码块的使用场景
    Java 枚举(enum) 详解7种常见的用法
    第一章 对象和封装
    摘抄Java反射
  • 原文地址:https://www.cnblogs.com/wulangzhou/p/3016587.html
Copyright © 2020-2023  润新知