zoukankan      html  css  js  c++  java
  • AC自动机妙用

    理解题意之后,很自然的想到了用AC自动机搞,结果网上一搜,全是暴搜,按照自己的思想,AC自动机搞起,果然在提交了数次之后,看到了Accept。

    AC自动机需要三个步骤:

    第一步:建立字典树;

    第二步:为字典树建立 Fail 指针 ;

    第三步:进行匹配;

    #include<iostream>
    #include<string>
    #include<string.h>
    #include<cctype>
    #include<queue>
    #include<stdio.h>
    
    #define max(x,y) ((x) > (y) ? (x) : (y))
    
    using namespace std ;
    
    struct Node	{
    	Node *next[26] ; 
    	Node *fail ;
    	bool is_over ;
    	int len ;
    };
    
    Node* new_node()	{
    	Node *root = new Node ;
    	root ->fail = NULL ;
    	for(int i = 0 ; i< 26 ; i++)
    		root->next[i] = NULL ;
    	root ->is_over = false ;
    	return root ;
    }
    
    void build_tree( Node *root , char *s )	{
    	int len = strlen(s) ;
    	for(int i = 0 ; i < len ; i++)	{
    		if(root->next[s[i] - 'a'] == NULL)
    			root->next[s[i] - 'a'] = new_node() ;
    		root = root ->next[s[i] - 'a'] ;
    	}
    	root ->is_over = true ;
    	root ->len = len ;
    }
    
    void build_fail(Node *root)	{
    	Node *r = root ;
    	queue< Node* > q ;
    	q.push(root) ;
    	while(!q.empty())	{
    		r = q.front() ;
    		q.pop() ;
    		Node *p = r ;
    		for(int i = 0 ; i < 26 ; i++)	{
    			if(p->next[i] != NULL)	{
    				if(p == root)	{
    					p->next[i]->fail = root ;
    					q.push(p->next[i]) ;
    					continue ;
    				}
    				while(r->fail->next[i] == NULL && r ->fail != root)
    					r = r->fail ;
    				if(r->fail ->next[i] != NULL)
    					p ->next[i]->fail = r ->fail ->next[i] ;
    				else
    					p ->next[i] ->fail = root ;
    				q.push(p->next[i]) ;
    			}
    		}
    	}
    }
    
    int A_C(Node *root , char *s)	{
    	int len = strlen(s) ;
    	Node *r = root ;
    	int count = 0 ;
    	for(int i = 0 ; i < len ; i++)	{
    		if(!isalpha(s[i]))
    			continue ;
    		if(r->next[s[i]-'a'] != NULL)	{
    			r = r ->next[s[i]-'a'] ;
    			if(r->is_over && !(islower(s[i+1])) && !(islower(s[i - r->len])) )	
    				count++ ;
    		}
    		else {
    			while(r->next[s[i]-'a'] == NULL && r != root )
    				r = r ->fail ;
    			if(r ->next[s[i] - 'a'] != NULL)
    				r = r ->next[s[i] - 'a'] ;
    			else
    				r = root ;
    			if(r->is_over && (!(isalpha(s[i+1])) ) && !(islower(s[i - r->len])) 	)	
    				count++ ;	
    		}
    	}
    	
    	return count ;
    }
    
    
    int main()	{
    	int n , m ; 
    	int t = 1 ;
    	while(scanf("%d%d",&n,&m) == 2)	{
    		Node *root = new_node() ;
    		Node *r = root ;
    		while(n--)	{
    			char s[30] ;
    			scanf("%s",&s) ;
    			getchar() ;
    			build_tree(root,s) ;
    			root = r ;
    		}
    		r->fail = NULL ;
    		root = r ;
    		build_fail(r) ;
    		char str[30][100] ;
    		char str1[30][100] ;
    		int count[30] = {0} ;
    		int ma = 0 ;
    		for(int i = 0 ; i < m ; i++)	{
    			gets(str[i]) ;
    			strcpy(str1[i],str[i]) ;
    			int len = strlen(str[i]) ;
    			for(int j = 0 ; j < len ; j++)
    				if(isupper(str[i][j]))
    					str[i][j] += 32 ;
    			count[i] = A_C(root,str[i]) ;
    			ma = max(ma,count[i]) ;
    		}
    		cout << "Excuse Set #" << t++ << endl;
    		for(int k = 0 ; k < m ; k++)
    			if(count[k] == ma)	
    				cout << str1[k] << endl ;
    			cout << endl ;
    	}
    	return 0 ;
    }
    
  • 相关阅读:
    认证-权限-频率组件
    视图组件
    序列化类
    解析模块
    异常模块
    响应模块分析
    请求模块分析
    cbv请求分析
    django中的restful规范
    web接口与restful规范
  • 原文地址:https://www.cnblogs.com/NYNU-ACM/p/4237457.html
Copyright © 2011-2022 走看看