NFA确定化c

这篇博客介绍了非确定有限状态自动机(NFA)的确定化过程,并提供了修正后的代码示例,包括NFA的最小化算法,帮助读者理解相关概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1:原文链接
2:代码块:(下面的代码错误已经修改)

#include<vector>
#include<queue>
#include<set>
#include<iostream>
#include<memory.h> 
#include<algorithm>
using namespace std;

void print(const set<int> &a){
	if(a.size()==0)return;
	//cout<<a.size();
	cout<<'{';
	set<int>::iterator it;
	for(it=a.begin();it!=a.end();++it)
		cout<<*it<<',';
	cout<<'\b'<<'}';
}
bool equal(set<int> &a,set<int> &b){
	if(a.size()!=b.size())return false;
	else{
		set<int>::iterator ia=a.begin();
		set<int>::iterator ib=b.begin();
		for(;ia!=a.end();++ia,++ib){
			if(*ia!=*ib)return false;
		}
	}
	return true;
}

int main()
{
	vector<int> I;
	cout<<"请输入有多少个转移字符(不包含epsilon):"<<endl;
	int Num_char;cin>>Num_char;
	
	cout<<"请输入转移字符(小写,保留e,e默认为epsilon,无需输入):"<<endl;
	char* change_char=new char[Num_char+1];*change_char='e';//change_char[]存储了所有的转移字符 
	
	for(int i=1;i<Num_char+1;++i)cin>>change_char[i];
	cout<<"请输入节点总数(0默认为start节点,包含在总数中):"<<endl;
	
	int Num_node;
	cin>>Num_node;
	
	int* node=new int[Num_node];
	
	for(int i=0;i<Num_node;++i)node[i]=i;
	
	char change[20][20]={};
	cout<<"请输入转移箭弧,格式为(开始节点编号  终点节点编号 转移字符)如 0 1 e。输入0 0 e结束输入"<<endl;
	
	int s,e;
	char c;
	while(cin>>s>>e>>c){
		if(s==0&&e==0&&c=='e')break;
		change[s][e]=c;
	};
	cout<<endl<<"输入状态邻接矩阵为:"<<endl<<"------------------------"<<endl;
	for(int i=-1;i<Num_node;++i){
		for(int j=-1;j<Num_node;++j){
			if(i==-1&&j==-1)cout<<" "<<" ";
			else if(i==-1)cout<<j<<" ";
			else if(j==-1)cout<<i<<" ";
			else
				cout<<change[i][j]<<" ";
		}
		cout<<endl;
	}
	cout<<endl<<"每个节点的e-closure为:"<<endl<<"-----------------------"<<endl;
	set<int>* node_epsilon=new set<int>[Num_node];//建立每个节点的e闭包set,便于之后的扩充
	for(int i=0;i<Num_node;++i){
		node_epsilon[i].insert(i);
		queue<int> que;que.push(i);//使用一个队列维护来进行宽度优先搜索(先找一步可达的所有位置)
		while(!que.empty()){
			int ii=que.front();
			for(int j=0;j<Num_node;++j){
				if(change[ii][j]=='e'/*&&node_epsilon[i].find(j)==node_epsilon[i].end()*/){
					node_epsilon[i].insert(j);
					que.push(j);
				}
			}
			que.pop();
		}
		print(node_epsilon[i]);cout<<endl;
	} 
	
	cout<<endl<<"确定化过程中构造的状态表为:"<<endl<<"----------------"<<endl;
	vector<set<int> > v;
	v.push_back(node_epsilon[0]);
	//vector<set<int> >::const_iterator it=v.begin();迭代器在每一次容器元素发生变化时都会失效!!坑!!
	int it=0;
	while(it<v.size()){
		cout<<"s"<<it<<":";print(v[it]);cout<<'\t'<<'\t';
		for(int i=1;i<Num_char+1;++i){//开始维护v[char],即单步字符的转移vector 
			char c=change_char[i]; 
			set<int> temp;//temp用来维护转移过程之中的集合,开副本,不再使用clear,为了保留在vector中值
			for(set<int>::iterator m=v[it].begin();m!=v[it].end();++m){
				for(int j=0;j<Num_node;++j){
					if(change[*m][j]==c){
						temp.insert(node_epsilon[j].begin(),node_epsilon[j].end());
					}
				}
			}
			print(temp);cout<<'\t'<<'\t';
			//开始判断该状态集合之前是否已经存在
			bool exists=false;
			for(int q=0;q<v.size();q++){
				//cout<<q;
				if(equal(v[q],temp)){
					exists=true;break;
				}
			}
			if(!exists){
				v.push_back(temp);//cout<<v.size()<<temp.size();
			}
   			//if(v.end()==find(v.begin(),v.end(),temp))v.push_back(temp);
		}
		++it;
		//print();//这里开始输出总是显示为空,猛然想到是不是vector保留的是一个指向内部元素的指针?而每次temp被clear之后便无法再恢复!!
		cout<<endl;
	}

 }

3:最小化;
4:

#include <iostream>
#include <vector>
#include <algorithm>
#include <math.h>
using namespace std
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值