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

一、实验目标
  
1、掌握有穷状态自动机的概念;  
2、掌握有穷状态自动机的存储及表示方法;
3、掌握有穷状态自动机与正则式之间的关系。
 
二、实验要求
  
1、输入正规式; 

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

3. 以五元组形式输出。

三、算法

参见教材

 

练习:

²  (a|b)*abb

²  l(l|d)*

²  1(1010*|1(010)*1)*0

 

四、完成算法设计、编码和调试工作,完成实验报告。

#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("\t请输入规则个数:"); 
  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("\t请输入文法:\n");
for(i = 0; i < line; i++)  {printf("\t");scanf("\t%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==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("\t是非确定的有穷状态自动机,即 NFA\n\n");
  printf("\t构造的有穷状态自动机为: \n");
  printf("\tNFA  N= ( K ,∑, M , {S} , {Z} ) \n");}
  else{printf("\t是确定的有穷状态自动机,即 DFA\n\n\n");
  printf("\t构造的有穷状态自动机为: \n");
  printf("\tDFA  D= ( K ,∑, M , {S} , {Z} ) \n");}
  printf("\t其中:\n\tK={S");
  for(i=0;i<30&&(VT[i]!='\0');i++){printf(" , %c",VT[i]);}
  printf("}\n");printf("\t∑ ={");
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]=='|'){count++;k=0;j++;}
}
}
count++;k=0;
}
printf("\n");printf("\tM:\n");l=0;
while(VN[l]!='\0')
{
printf("\tM(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("\tM(%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");
  
}
原文地址:https://www.cnblogs.com/liangyao111/p/6150449.html