实现NFA到DFA的转化(C语言)

简单记录一下,自动机课上的一个实验,用C语言实现NFA到DFA的转化,使用的是子集构造法。
子集构造法相信大家都会,直接甩代码。
先是把NFA和DAF的转移表存储在数据结构里,这里用了二维字符数组,先是定义了一个struct onechar,用来当作转移表的一格,这让我这个程序简单了不少,但是局限性是真的多。所以程序的状态只能使用当个字符表示,且设置的最大状态集数量是20。

typedef struct onechar
{
	char block[MAX_NUM];//用于存储一个20个字符的字符数组
}onechar;

后面的函数调用其实有点混乱,功能分配很奇怪。
子集构造法被我写成了字符匹配算法,以下是主要函数。解释我直接写在注释里好了。

void switch_NFAtoDFA(onechar** NFA_chart, onechar** DFA_chart, char* NFA_status, onechar* DFA_status)
{
	int i = 0, j = 0, n = 0, flag = 1;//NFA与DFA转移表的第一行是相同的,num是DFA的状态集数量
	DFA_status[0].block[0] = NFA_status[0];
	DFA_status[0].block[1] = '\0';
	while (n != num)
	{
		switch1(NFA_chart, DFA_chart, NFA_status, DFA_status[n].block, n);/*这个函数把DFA的新得到的状态去匹配NFA的转移表,从而得到DFA的一行*/
		//以下的几个for循环是把新得到的一行中的状态与DFA的状态集对比,看是否有新状态
		for (i = 0; i < chars_num; i++)
		{
			for (j = 0; j < num; j++)//n,表示已经求完第n个状态的转移函数
			{
				if (strcmp(DFA_chart[n][i].block, DFA_status[j].block) == 0)//不匹配说明是新状态(所有不匹配才可以)
				{
					flag = 0;//已存在的状态
				}
			}
			if (flag == 1 && DFA_chart[n][i].block[0] != '#')//新状态当然要放在DFA状态集里了
			{
				strcpy(DFA_status[num].block, DFA_chart[n][i].block);
				num++;
			}
			flag = 1;
		}
		n++;}

这里是我最后发现的bug,程序会把状态一样但是字符顺序不一样的状态写成两个状态,如pqr和prq,后来发现只要排下序就好了。

for (i = 0; i < j - 1; i++)//冒泡排序,防止出现pqr,rpq是不同状态
	{
		for (k = 0; k < j - 1; k++)
		{
			if (s[k] > s[k + 1])
			{
				char tmp = s[k];
				s[k] = s[k + 1];
				s[k + 1] = tmp;
			}
		}
	}

就简单写到这里把,本人很懒,但是直接甩代码实在不太好,就稍微写几个字,刚开始写博客记录,思维有些混乱很抱歉。附上完整代码,大家一起互相学习。
附上测试用例:
在这里插入图片描述

NFA转DFA完整代码在gitee上

附github 👆前往

NFA(非确定性有限自动机)是一种计算模型,用于描述一类自动机,其能够同时有多个可能的转移状态。与之相对应的,DFA(确定性有限自动机)在任何给定时刻只有一个状态。 利用C语言NFA转化DFA的过程可以简要地概括如下: 第一步,我们需要先根据给定的NFA构建相应的DFA数据结构。一个DFA数据结构通常包含有限个状态、输入字符集、初始状态以及接受状态集合等属性。 第二步,我们需要确定DFA的初始状态。对于NFA构建DFA的过程,通常会有多个可能的初始状态。这是因为NFA的初始状态可能会有多个,我们需要将这些可能的初始状态同时引入DFA中。 第三步,我们需要确定DFA的接受状态集合。对于NFA的每个接受状态,我们需要在DFA中找到所有可能的转移路径,并将其标记为接受状态。 第四步,我们需要确定DFA的状态转移函数。对于任意给定的输入字符和当前状态,在NFA中可能存在多个状态转移路径。我们需要根据这些可能的路径确定DFA中对应的状态转移。 第五步,我们需要重复进行第四步,直到所有可能的状态转移都已经确定。 最后,我们可以利用C语言编写代码实现上述转换过程。我们可以通过定义结构体表示NFADFA的数据结构,并编写函数来进行数据结构的初始化、状态转移等操作。 需要注意的是,NFA转化DFA的过程是一种指数级的计算,所以在实际编程中需要注意性能问题,对于较大规模的NFA,可能需要采用一些优化策略来减少计算时间和空间复杂度。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值