AC_Automata模板

#include<bits/stdc++.h>
using namespace std;
#define ll long long

int ans=0;

const int maxnode=1e6+7;  
const int sigma_size=26;
struct AC_Automata  
{  
    int ch[maxnode][sigma_size];  
    int val[maxnode];   // 每个字符串的结尾结点都有一个非0的val  
    int f[maxnode];     // fail函数  
    int last[maxnode];  // last[i]=j表j节点表示的单词是i节点单词的后缀,且j节点是单词节点  
    int sz;  
  
    //初始化0号根节点的相关信息  
    void init()  
    {  
        sz=1;  
        memset(ch[0],0,sizeof(ch[0]));  
        val[0]=0;  
    }  
  
    void insert(char *s,int v)  
    {  
        int u=0;  
        for(int i=0; s[i]; i++)  
        {  
            int id=s[i]-'a';  
            if(ch[u][id]==0)  
            {  
                ch[u][id]=sz;  
                memset(ch[sz],0,sizeof(ch[sz]));  
                val[sz++]=0;  
            }  
            u=ch[u][id];  
        }  
        val[u]+=v;  
    }  
   
    void getFail()  
    {  
        queue<int> q;  
        last[0]=f[0]=0;  
        for(int i=0; i<sigma_size; i++)  
        {  
            int u=ch[0][i];  
            if(u)  
            {  
                f[u]=last[u]=0;  
                q.push(u);  
            }  
        }  
  
        while(!q.empty())// 按BFS顺序计算fail  
        {  
            int r=q.front(); q.pop();  
            for(int i=0; i<sigma_size; i++)  
            {  
                int u=ch[r][i];  
                if(u==0)continue;  
                q.push(u);  
  
                int v=f[r];  //失配边尝试平行传递
                while(v && ch[v][i]==0) v=f[v];  
                f[u]= ch[v][i];  
                last[u] =  val[f[u]]?f[u]:last[f[u]];  
            }  
        }  
    }  
  
    //递归打印与结点i后缀相同的前缀节点编号  
    //进入此函数前需保证val[i]>0  
    void print(int i)  
    {  
        if(i)  
        {  
			ans+=val[i];
			val[i]=0;			
			print(last[i]);  
        }  
    }  
  
    void find(char *s)  
    {  
        int j=0;//j:trie树中的节点编号  
        for(int i=0; s[i]; i++)  
        {  
            int id=s[i]-'a';  
            while(j && ch[j][id]==0) j=f[j];//ch[j][id]:第j个节点的id字母子节点编号 
            j=ch[j][id];  
            if(val[j]) print(j);  
            else if(last[j]) print(last[j]);  
        }  
    }  
  
};  
AC_Automata ac;  

const int maxn=1e6+7;
char ori[maxn];
char tar[maxn];

int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		ans=0;
		ac.init();
		int n;
		scanf("%d",&n);
	
		for(int i=1;i<=n;i++){
			scanf("%s",tar);
			ac.insert(tar,1);
		}
	
		ac.getFail();
		scanf("%s",ori);
		ac.find(ori);
		printf("%d\n",ans);
	}
}

自动机的英文念起来好中二啊,

自动机就是trie树和kmp算法的组合,多模板匹配的首选算法

两种快乐的算法重叠在一起,就有了自动机(

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

贴一个轻量化的板子,原题HDU3065

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=2e6+7;
const int maxm=55;
const int maxnode=1010*51;
const int sigma=128-30;

int n,m;
int vis[1010];
char word[1010][55];
char ori[maxn];

struct automata{
	int ch[maxnode][sigma];
	int val[maxnode];
	int f[maxnode];
	int sz;

	int newnode(){
		memset(ch[sz],0,sizeof(ch[sz]));
		f[sz]=val[sz]=0;
		return sz++;
	}

	void init(){
		memset(val,0,sizeof(val));
		sz=0;
		newnode();
	}

	void insert(char s[],int v){	
		int u=0;
		for(int i=0;s[i];i++){
			int &x=ch[u][s[i]-30];
			u=x?x:x=newnode();	
		}
		val[u]=v;
	}

	void build(){
		queue<int>q;
		q.push(0);	
		while(!q.empty()){
			int u=q.front();q.pop();
			for(int i=0;i<sigma;i++){
				int v=ch[u][i];
				if(!v)ch[u][i]=ch[f[u]][i];
				else q.push(v);
				if(u&&v)f[v]=ch[f[u]][i];
			}
		}
	}
	
	int find(char s[]){
		int j=0;
		for(int i=0;s[i];i++){
			int id=s[i]-30;
			j=ch[j][id];
			int tmp=j;
			while(tmp){
				vis[val[tmp]]++;
				tmp=f[tmp];
			}
		}
	}
}ac;

int main(){
	while(~scanf("%d",&n)){
		memset(vis,0,sizeof(vis));		
		ac.init();
		for(int i=1;i<=n;i++){
			scanf("%s",word[i]);
			ac.insert(word[i],i);
		}
		ac.build();

		scanf("%s",ori);
		ac.find(ori);
		
		for(int i=1;i<=n;i++){
			if(vis[i])printf("%s: %d\n",word[i],vis[i]);
		}
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一个基于Python语言实现的自动机确定化和最小化的代码示例。以下是代码: ``` # 自动机类 class Automata: def __init__(self): self.states = [] # 状态集合 self.alphabet = [] # 字母表 self.transitions = {} # 转移函数 self.start_state = '' # 初始状态 self.final_states = [] # 终止状态 # 读取自动机文件 def read_file(self, file_path): with open(file_path, 'r') as f: lines = f.readlines() self.states = lines[0].strip().split(',') self.alphabet = lines[1].strip().split(',') self.transitions = dict() for line in lines[2:-2]: state, symbol, next_state = line.strip().split(',') if (state, symbol) not in self.transitions: self.transitions[(state, symbol)] = [next_state] else: self.transitions[(state, symbol)].append(next_state) self.start_state = lines[-2].strip() self.final_states = lines[-1].strip().split(',') # 判断自动机是否确定 def is_deterministic(self): for state in self.states: for symbol in self.alphabet: if (state, symbol) not in self.transitions: return False if len(self.transitions[(state, symbol)]) > 1: return False return True # 自动机确定化 def determinize(self): if self.is_deterministic(): return self else: new_states = [] new_transitions = {} new_final_states = [] unmarked_states = [] marked_states = [] new_start_state = tuple(sorted([self.start_state])) new_states.append(new_start_state) unmarked_states.append(new_start_state) while len(unmarked_states) > 0: current_state = unmarked_states.pop() marked_states.append(current_state) for symbol in self.alphabet: next_state = [] for state in current_state: if (state, symbol) in self.transitions: next_state += self.transitions[(state, symbol)] if len(next_state) > 0: next_state = tuple(sorted(list(set(next_state)))) if next_state not in new_states: new_states.append(next_state) unmarked_states.append(next_state) if (current_state, symbol) not in new_transitions: new_transitions[(current_state, symbol)] = [next_state] else: new_transitions[(current_state, symbol)].append(next_state) if set(current_state).intersection(set(self.final_states)): new_final_states.append(current_state) new_automata = Automata() new_automata.states = new_states new_automata.alphabet = self.alphabet new_automata.transitions = new_transitions new_automata.start_state = new_start_state new_automata.final_states = new_final_states return new_automata # 自动机最小化 def minimize(self): if self.is_deterministic(): new_automata = Automata() new_automata.states = self.states new_automata.alphabet = self.alphabet new_automata.transitions = self.transitions new_automata.start_state = self.start_state new_automata.final_states = self.final_states return new_automata else: dfa = self.determinize() partitions = [set(dfa.final_states), set(dfa.states) - set(dfa.final_states)] unmarked_partitions = [set(dfa.final_states)] marked_partitions = [set(dfa.states) - set(dfa.final_states)] while len(unmarked_partitions) > 0: current_partition = unmarked_partitions.pop() marked_partitions.append(current_partition) for symbol in dfa.alphabet: next_partitions = [] for partition in current_partition: next_partition = set() for state in partition: if (state, symbol) in dfa.transitions: next_partition.add(dfa.transitions[(state, symbol)][0]) else: next_partition.add(state) next_partitions.append(next_partition) for next_partition in next_partitions: if next_partition not in partitions: partitions.append(next_partition) unmarked_partitions.append(next_partition) new_states = [] new_transitions = {} new_final_states = [] for partition in partitions: new_states.append(tuple(sorted(list(partition)))) for state in new_states: for symbol in dfa.alphabet: next_state = tuple(sorted(list(set([s for p in state for s in partitions[partitions.index(p) + 1] if (p, symbol) in dfa.transitions]))))) if len(next_state) > 0: if (state, symbol) not in new_transitions: new_transitions[(state, symbol)] = [next_state] else: new_transitions[(state, symbol)].append(next_state) for state in new_states: if set([s for s in state for p in dfa.final_states if s in p]): new_final_states.append(state) new_automata = Automata() new_automata.states = new_states new_automata.alphabet = dfa.alphabet new_automata.transitions = new_transitions new_automata.start_state = tuple(sorted([dfa.start_state])) new_automata.final_states = new_final_states return new_automata ``` 这段代码实现了自动机类,并包含了读取自动机文件、判断自动机是否确定、自动机确定化、自动机最小化等方法。您可以使用该类,结合文件读取操作,来实现您的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值