DFA的编程实现

来源:互联网 发布:双色球走势图软件 编辑:程序博客网 时间:2024/06/05 16:03

附录(源代码如下):

/**
文本说明:
m n t a
4 2 1 10  分别代表有:m=4个状态,n=2个字符变量,t=1个接收状态,a=10个测试用例 
0 1 2 3   分别代表4个状态分为是什么 
a b       分别代表字符变量 
0         代表起始状态 
1 2       从这里开始4行2列代表状态转换表 
3 2
1 3
3 3
3         最后一行代表1个接收状态 
*/ 
#define LENOFINE 256
#include <iostream>
#include <cstring>
#include <fstream>
#include <stdio.h>
#include <conio.h>
#include <windows.h>


using namespace std;


long m,n,t,a;   //分别代表有:m个状态,n个字符变量,t个接收状态,a个测试用例
long s[1000][1000]; //存储转移矩阵
long Accept[1000];  //存储接受状态
int  status[1000]; //status存储状态
char by[1000];    //by存储字符集 
int  start=-1;    //记录起始状态 


void  dfs(int  N,long s[1000][1000],long Accept[1000],int  now,string str="")
{
if(N<0)
{
return ;
}
N--;
if(Accept[now]==1)
{
cout<<str<<endl;
}
for(int i=0;i<n;i++)
{
string temp;
int nowtemp;
nowtemp=now;
temp=str;
str+=by[i];

now=s[now][i];
dfs(N,s,Accept,now,str);
str=temp;
now=nowtemp;
}
}




int  buildFile()
{
FILE *fp;
char filename[LENOFINE];
char strTmp[121];
cout<<"请输入文件名:";
    gets(filename);
int n=0;
fp=fopen(filename,"w");
if(fp==NULL)
{
cout<<"无法创建文件"<<filename<<endl;
exit(0); 
}
cout<<"请输入文件内容:"<<endl<<endl;


while(strlen(gets(strTmp))>0)
{
fputs(strTmp,fp);
fputs("\n",fp);
n++;
}
fclose(fp);
return  n;
}


void  dispFile()
{
    cout<<"开始进行DFA操作:"<<endl;
    start=-1,n=0,m=0,t=0,a=0;
for(int i=0;i<1000;i++)
{
for(int j=0;j<1000;j++)
{
s[i][j]=0;
}
Accept[i]=0;
status[i]=0;
by[i]=0;
}


    //读取文件 
    FILE *fp;
    char fname[LENOFINE];
    cout<<"请输入文件名:";
    gets(fname);
    // fp=fopen("DFA.txt","r");
        fp=fopen(fname,"r");
    if(fp==NULL)
    {
    cout<<"文件打开错误!"<<endl;
    exit(0);

   fscanf(fp,"%d %d %d %d",&m,&n,&t,&a);
   cout<<m<<" "<<n<<"  "<<t<<"  "<<a<<"  "<<endl;
   cout<<"状态集如下:"<<endl;
   for(int i=0;i<m;i++)
   {
    fscanf(fp,"%d ",&status[i]);
    cout<<status[i]<<"  ";
}
cout<<endl;

//检查状态集中的状态是否唯一
for(int i=0;i<m-1;i++)
{
for(int j=i+1;j<m;j++)
{
if(status[j]==status[i])
{
printf("此状态集错误,…状态 %d.发生重复!\n",status[j]); 
}
}


cout<<"字符集如下:"<<endl;
   for(int i=0;i<n;i++)
   {
    fscanf(fp,"%c ",&by[i]);
    cout<<by[i]<<"  ";
}
cout<<endl;
//检查字符集元素是否唯一 
for(int i=0;i<n-1;i++)
{
for(int j=i+1;j<n;j++)
{
if(by[j]==by[i])
{
printf("此状态集错误,…状态 %d.发生重复!\n",by[j]); 
}
}




//读取起始状态
fscanf(fp,"%d",&start);

//DFA的起始状态的正确性检查 
bool flag1=false;
for(int i=0;i<m;i++)
{
if(start==status[i])
{
flag1=true;
break;

}
if(flag1)
{
cout<<"起始状态是=>  "<<start<<endl; 
}
else
{
cout<<"起始状态不在状态集之内!"<<endl;
}


//读取状态转换表 
bool flag2=false;
bool flag4=true;
cout<<"字符转换表如下: "<<endl; 
        memset(s,0,sizeof(s));
        memset(Accept,0,sizeof(Accept));
        for(int i = status[0];i<(status[0]+m);i++){
       
            for(int j = 0;j<n;j++)
            {
            flag2=false;
            //cin>>s[i][j];
                fscanf(fp,"%d ",&s[i][j]);
                
                //DFA的状态转换表的正确性检查 
        for(int k=0;k<m;k++)
        {
        if(s[i][j]==status[k])
        {
        flag2=true;
        break;
       
        }
        if(flag2)
        {
        cout<<s[i][j]<<"  ";
       
        }
        else
      {
      
      flag4=false;
       
}
             cout<<endl;  
        }
        if(!flag4){
        cout<<"状态转移表状态不在状态集之内!非法DFA"<<endl;
}
        //读取接收状态
cout<<"接收状态如下:"<<endl; 
bool flag3=false;
        for(int i = 0;i<t;i++){
        flag3=false;
            long temp;
            //cin>>temp;
            fscanf(fp,"%d ",&temp);
            
            //DFA的接收状态的正确性检查 
    for(int j=0;j<m;j++)
    {
    if(temp==status[j])
    {
    flag3=true;
    break;
   
      }
    if(flag3)
    {

    cout<<temp<<"  ";
                Accept[temp] = 1;
    }
    else
    {
    cout<<"接收状态不在状态集之内!"<<endl;
    break;
    }
        }
        cout<<endl;
        
        int  len=0;
        int now;
        
        /**第4题:DFA的语言集列表显示*/
        cout<<"输出可识别的规定长度的串:"<<endl;
        cout<<"len <= ";
cin>>len; 
   
        string  str=" ";
        dfs(len,s,Accept,start,str);
        
        
        cout<<"请输入 <"<<a<<"> 个测试用例:"<<endl; 
        bool flag5=true; 
        while(a--){
        flag5=true;
            string temps;
            cout<<"还可以测试 <"<<a+1<<">个串: ";
            cin>>temps;
            int after = start;
            cout<<"状态路径为 :"<<endl<<"===>"<<start;
            int byaim=-1;
            for(int i = 0;i<temps.length();i++){
            for(int j=0;j<n;j++)
            {
            if(temps[i]==by[j])
            {
            //cout<<"temps[i]="<<temps[i]<<"  by[j]="<<by[j]<<endl;
            byaim=j;
            break;
}
}
if(byaim!=-1)
{
after = s[after][byaim];
cout<<" ===>  "<<after;
byaim=-1;
}
else
{
after=1000;
cout<<endl<<temps[i]<<" 字符不在字符集之内!"<<endl;
flag5=false;
break;
}
            }
            
            
            if(Accept[after]==1&&flag5)
            {
            cout<<"YES"<<endl;
}
            else
            {
            cout<<"NO"<<endl;

            cout<<endl;
        }
fclose(fp);
//}
}






int main(){

int flag=1;
char ctmp;
char fname[LENOFINE];
while(flag>0)
{
system("cls");
cout<<"          DFA的基本操作          "<<endl;
cout<<"================================="<<endl;
cout<<"1、创建dfa文件                   "<<endl;
cout<<"2、读取文件内容并测试            "<<endl;
cout<<"0、退出                          "<<endl;
cout<<"================================="<<endl;
cout<<"请选择:  ";
scanf("%d",&flag);
ctmp=getchar(); 
if(flag>0)
{
//cout<<"请输入文件名: ";
//gets(fname);
switch(flag)
{
case 1:
buildFile();
break;
case 2:
dispFile();
break;
default:
cout<<"输入错误!"<<endl;
break;

}
}
    
    //return 0;
}

0 0