zoukankan      html  css  js  c++  java
  • 实验三 有限自动机的构造与识别

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

     

    一、实验目标
      
    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");
    
    }
    
  • 相关阅读:
    HTML基础
    Java基础05-计算机单位
    Java基础04-运算符
    Java基础03-数据类型
    Java基础02-变量
    Java基础01-HelloWorld
    MarkDown基本使用
    短视频学习
    c# as 总结
    在C#中使用Nullable类型和 tuple类
  • 原文地址:https://www.cnblogs.com/a305810827/p/6102495.html
Copyright © 2011-2022 走看看