有穷的自动机构造

#include<string.h>
#include<stdio.h>
#include<stdlib.h>
int main()
{
char p[30][30];//存放文法
char q[30][30];
int line=0;
int n;
int i,j;
int count=0;
int k,t=0;
int flag=0;
int l,m=0;
char VN[30]={‘\0‘};//存放非终结符号
char VT[30]={‘\0‘};//存放终结符号
printf("请输入规则个数");
scanf("%d",&n);
line=n;
for(i=0;i<30;i++)//给字符串数组p,q全部赋值为‘\0‘
for(j=0;j<30;j++)
{
p[i][j]=‘\0‘;
q[i][j]=‘\0‘;
}
printf("请输入文法:\n");
for(i=0;i<line;i++)
{
scanf("%s",p[i]);
}
//把字符分为终结符和非终结符
l=0;
m=0;
for(i=0;i<line;i++)
{
for(j=0;j<30&&(p[i][j]!=‘\0‘);j++)
{
//非终结符放入数组VN中
if(p[i][j]<=‘z‘&&p[i][j]>=‘a‘||(p[i][j]<=‘9‘&&p[i][j]>=‘0‘))
{
flag=0;
for(t=0;VN[t]!=‘\0‘;t++)
{
if(VN[t]==p[i][j])
{
flag=1;break;
}
}
if(flag==0)
{
VN[l]=p[i][j];
l++;
}
}
//终结符放在数组VT中
if(p[i][j]<=‘Z‘&&p[i][j]>=‘A‘)
{
flag=0;
for(t=0;t<30&&(VT[t]!=‘\0‘);t++)
{
if(VT[t]==p[i][j])
{
flag=1;
break;
}
}
if(flag==0)
{
VT[m]=p[i][j];
m++;
}
}
}
}
//把规则右部分分离,放入数组q中
count=0;
k=0;
for(i=0;i<line;i++)
{
for(j=4;j<30&&(p[i][j]!=‘\0‘);j++)
{
if((p[i][j]<=‘z‘&&p[i][j]>=‘a‘)||(p[i][j]<=‘Z‘&&p[i][j]>=‘A‘)||(p[i][j]<=‘9‘&&p[i][j]>=‘0‘))
{
q[count][k]=p[i][j];
k++;
}
else
{
count++;
k=0;
}
}
count++;
k=0;
}
//判断是确定的还是非确定的有穷状态自动机,并进行前半部分打印
//判断依据:q数组中每一行字符串是否相同
flag=0;
for(i=0;i<count;i++)
{
for(j=i+1;j<count;j++)
{
if(strcmp(q[i],q[j])==0)
{
flag=1;
break;
}
}
}
if(flag==1)
{
printf("是非确定的有穷状态自动机,即NFA\n\n");
printf("构造的有穷状态自动机为:\n");
printf("NFA N=(K,E(总和的意思),M,{S},{Z})\n");
}
else
{
printf("是确定的有穷状态自动机,即DFA\n\n\n");
printf("构造的有穷状态自动机为:\n");
printf("DFA N=(K,E(总和的意思),M,{S},{Z})\n");
}
printf("其中,\nK={S");
for(i=0;i<30&&(VT!=‘\0‘);i++)
{
printf(",%c",VT[i]);
}
printf("}\n");
printf("E={");
for(i=0;i<30&&(VN[i]!=‘\0‘);i++)
{
printf("%c ",VN[i]);
}
printf("}\n");
//分离文法
k=0;
count=0;
for(i=0;i<line;i++)
{
j=4;
while(p[i][j]!=‘\0‘)
{
if(k<4)
{
q[count][k]=p[i][k];
k++;
}
else
{
if((p[i][j]<=‘z‘&&p[i][j]>=‘a‘)||(p[i][j]<=‘Z‘&&p[i][j]>=‘A‘)||(p[i][j]<=‘9‘&&p[i][j]>=‘0‘))
{
q[count][k]=p[i][j];
k++;
j++;
}
if(p[i][j]==‘l‘)
{
count++;
k=0;
j++;
}
}
}
count++;
k=0;
}
printf("\n");
//打印M后部分
printf("M:\n");
l=0;
while(VN[l]!=‘\0‘)
{
printf("M(S,%c)={",VN[l]);
for(i=0;i<30;i++)
{
for(j=4;j<30&&(q[i][j]!=‘\0‘);j++)
{
if(VN[l]==q[i][j]&&(q[i][j+1]==‘\0‘)&&(q[i][j-1]==‘=‘))
printf("%c",q[i][0]);
}
}
printf("}\t");
l++;
}
printf("\n");
l=0;k=0;
while(VT[k]!=‘\0‘)
{
l=0;
while(VN[l]!=‘\0‘)
{
printf("M(%c,%c)={",VT[k],VN[l]);
for(i=0;i<30;i++)
{
for(j=4;j<30&&(q[i][j]!=‘\0‘);j++)
{
if(VT[k]==q[i][j]&&VN[l]==q[i][j+1])
printf("%c",q[i][0]);
}
}
printf("}\t");
l++;
}
k++;
printf("\n");
}
system("pause");
}

时间: 2024-08-04 18:31:53

有穷的自动机构造的相关文章

有穷状态自动机

实验三有限自动机的构造与识别 专业:商业软件工程   姓名:陈蔓嘉  学号:201506110245 一.   实验目的 1.掌握有穷状态自动机的概念: 2.掌握有穷状态自动机的存储及表示方法: 3.掌握有穷状态自动机与正则式之间的关系. 二.   实验要求 1.输入正规式: 2.构造该正规式的有穷状态自动机: 3. 以五元组形式输出. 三.    算法 1. 参见教材的转换规则. 四.  实验方法.步骤及结果测试 实验方法: 源程序名:压缩包文件(rar或zip)词法分析程序.zip 源程序名

hdu 5008 Boring String Problem(后缀自动机构造后缀树)

hdu 5008 Boring String Problem(后缀自动机构造后缀树) 题意:给出一个字符串s,然后每次询问一个k,求s的所有子串中,字典序第k小的是谁?多个解,则输出最左边的那个 解题思路:这道题应该是为后缀树量身定制的吧.只要构造出了后缀树,然后按字典序遍历就可以得出每个节点包含的子串的字典序的范围了,而且必然是个连续的区间范围.但是我不会后缀树啊..比赛的时候突然想到,后缀自动机是可以构造后缀树的,虽然以前没写过,但还是硬着头皮上吧,居然还真的让我给撸出来了.我的做法是这样的

构造该正规式的有穷状态自动机

#include<stdio.h> #include <ctype.h> #define ok 1 #define error 0 #define MAXREGLUARLONG 40 #define MAXSTATELONG 40 #define MAXCAHRSLONG 40 typedef int state; int iCurrentState=0; //初态以1开始 int iPreState=0; int iLastForkState=0; int iForkState=

BZOJ 2434 NOI 2011 阿狸的打字机 AC自动机构造fail树

题目大意:有一种打字机上有28个字母,分别是26个小写字母和BP,其中B代表退格,P代表换行,每一行就是一个字符串.现在给这些字符串标号,并询问x串在y串中出现过几次. 思路:这算是NOI史上最难的字符串的题了吧(动物园). 首先按照题意不难建一个AC自动机出来,按照正常的思路,对于每一个询问都需要在AC自动机上暴力的查找.但这样时间会十分好看. 于是我们想,fail指针构成的一定是一棵树,将这颗树的DFS序搞出来的话会有非常好的性质--串中存在某个字串的一定在这个字串的子树中,也就是对应DFS

【XSY1552】自动机 构造

题目大意 给你一个自动机,包含\(n\)个状态,指令集为前\(m\)个小写字母,对于每个状态\(s\)和每个指令\(i\),自动机均有后继\(T(s,i)\).请你求出一个长度不超过\(2^{20}\)的指令序列,使得无论自动机当前处在哪个状态(包括初始状态),按顺序执行指令序列的所有指令后,自动机都处于初始状态\(1\).无解输出\([impossible]\) \(1\leq n\leq 100,1\leq m\leq 26\) 题解 首先要证明一个结论:原问题有解等价于对于任意状态\(i\

编译原理DFA(有限确定自动机)的构造

原题: 1.自己定义一个简单语言或者一个右线性正规文法 示例如(仅供参考)  G[S]:S→aU|bV    U→bV|aQ V→aU|bQ     Q→aQ|bQ|e 2.构造其有穷确定自动机,如 3.利用有穷确定自动机M=(K,Σ,f, S,Z)行为模拟程序算法,来对于任意给定的串,若属于该语言时,该过程经有限次计算后就会停止并回答“是”,若不属于,要么能停止并回答“不是”       K:=S: c:=getchar; while c<>eof do {K:=f(K,c); c:=get

1211-有限自动机的构造与识别

#include<string.h>#include<stdio.h>#include<stdlib.h>int main(){char p[30][30];char q[30][30];int line=0;int n;int i,j;int count=0;int k,t=0;int flag=0;int l,m=0;char VN[30]={'\0'};char VT[30]={'\0'};printf("规则数:");scanf("

实验三 有限自动机的构造与识别

一.实验目标 1.掌握有穷状态自动机的概念: 2.掌握有穷状态自动机的存储及表示方法: 3.掌握有穷状态自动机与正则式之间的关系. 二.实验要求 1.输入正规式: 2.构造该正规式的有穷状态自动机: 3. 以五元组形式输出. 三.算法 参见教材的转换规则. 练习: 2  (a|b)*abb 2  l(l|d)* 2  1(1010*|1(010)*1)*0 四.完成算法设计.编码和调试工作,完成实验报告. #include<string.h> #include<stdio.h> #

1118有限自动机的构造与识别

1 #include<string.h> 2 #include<stdio.h> 3 #include<stdlib.h> 4 int main() 5 { 6 char p[30][30]; 7 char q[30][30]; 8 int line=0; 9 int n; 10 int i,j; 11 int count=0; 12 int k,t=0; 13 int flag=0; 14 int l,m=0; 15 char VN[30]={'\0'}; 16 ch