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


    一、        实验目的

     

          1、掌握有穷状态自动机的概念;  
          2、掌握有穷状态自动机的存储及表示方法;
          3、掌握有穷状态自动机与正则式之间的关系。
     

    二、        实验内容和要求

          1、输入正规式; 

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

          3、以五元组形式输出。

    三、        实验方法、步骤及结果测试

     

    1. 1.     源程序名:压缩包文件(rarzip)中源程序名shiyan3.c

    可执行程序名:E:\编程练习\C语言\C_FILE\Debug\shiyan3.exe

    1. 2.     主要程序段及其解释:

    #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");

    }

    1. 3.     运行结果及分析

     

  • 相关阅读:
    电容的用法:去耦、旁路、滤波等
    成为出色工程师的十大要素
    常用三极管的区别 9012 9013 9014 9015 8550 8050
    照明的几个光学概念
    PCB元件封装
    为什么诈骗短信看上去那么弱智
    摄像·镜头
    LED家居照明
    光色的应用与照度范围
    PowerPCB(PADS)常见问题全集
  • 原文地址:https://www.cnblogs.com/cs007/p/6102814.html
Copyright © 2020-2023  润新知