实验A---- ADFA的可判定性

Problem description
ADFA={< B,w >|B是DFA,w是串,B接收w}证明:ADFA是可判定的。 实验方法:编写一个算法/程序,对于任意给定的输入,可以判定ADFA

Input
有多个测试序列,测试结束于测试文件结束;每个测试序列的第一行为几个正整数n m t a分别表示有n个状态,从a开始m个小写字母组成的字符集,第一个状态默认为起始状态。t个接受状态和a个测试串,接下来为一个n行m列的矩阵S,其中S[i][j]表示第i行第j列,意义为状态i经过字母j到达状态S[i][j]。接下来有t个数字,表示t个接受状态值,然后是a行,每行一个串表示待测试的串。
Output
对于每个字符串输出YES表示该DFA接受该串,NO表示不接受。
Sample Input
3 3 1 2
2 3 2
3 3 3
3 3 3
2
a
b
Sample Output
YES
NO
题目理解:矩阵的行代表状态:状态1,2,3;矩阵的列代表字母第1列就是字母a,第2列是字母b,以此类推。倒数第三行表示的一个接受状态值2.即状态2是接受状态。
代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<string.h>
using namespace std;

//对每个输入的测试串儿都去模拟运行DFA,返回最后停留在哪个状态(因为DFA的下一个状态总是确定的)
int simulateDFA(char* test,int** array)
{
	int i;
	//从第一个状态array[0][0]开始模拟
	//首先获取test测试串的长度,test:abcde,,模拟运行length步
	int length = strlen(test);
	int row = 0;
	int column = test[0] - 'a';//列的计算通过 字符-'a'
	int destination;
	destination = array[row][column];
	for(i=1;i<length;i++)
	{
		column = test[i]-'a';
		row=destination-1;
		destination = array[row][column];
	}
	return destination;
}

bool check(int *accept, int result,int t)
{
	int i;
	for(i=0;i<t;i++)
	{
		if(accept[i]==result)
			return true;
	}
	return false;
}

int main()
{
	int n;//状态数
	int m;//字符数
	int t;//t个接受状态
	int a;//a个测试串
	while(scanf("%d %d %d %d",&n,&m,&t,&a)!=EOF)
	{
		//第一行输入
		//C++动态建立一个n行m列的二维数组
		int **array = new int*[n];//分配一个指针数组,将其首地址保存在array中 
		int i,j;
		for(i=0;i<n;i++)
			array[i] = new int[m];//为指针数组的每个元素分配一个数组
		//输入矩阵
		for(i=0;i<n;i++)
			for(j=0;j<m;j++)
			{
				scanf("%d",&array[i][j]);
			}
		//C++动态建立一维数组--->存放接受状态
		//int *accept = new int[t];
		//建立静态数组
		int accept[10000];
		for(i=0;i<t;i++)
			scanf("%d",&accept[i]);
		//输入a个测试串(字符)
		//C++动态建立二维数组--->存放a个测试串
	//	char **test = new char*[a];
		//静态分配二维数组
		char test[100][100];
		/*
		for(i=0;i<n;i++)
			test[i] = new char[m];
		for(i=0;i<a;i++)
			cin>>test[i];*/
		for(i=0;i<a;i++)
			scanf("%s",&test[i]);
		
		//以上都是输入
		//下面开始模拟DFA
		
		int result;
		//对每一个测试串去模拟运行DFA,并输出结果
		for(i=0;i<a;i++)
		{
			//模拟得到终点状态
			result = simulateDFA(test[i],array);
			//判断终点状态是否接受
			if(check(accept,result,t))
				cout<<"YES"<<endl;
			else
				cout<<"NO"<<endl;	
		}
		delete array;
	}
	return 0;
}

在测试过程中遇到很多问题:

1. wrong answer:在老师的指点下发现原来是审题出现了问题:我因为看到样例输入就只有一个DFA,所以写的代码就只能判定一个DFA但实际上程序应该能连续识别多个DFA的测试。

2. Runtime error: Runtime error有三个原因,不过我现在只记得两个了:一是除0,二是爆栈。在我的程序中除0是不可能的了,只能是因为爆栈了。

啊哈,因为我是用C++new去动态分配数组的,而且我在程序中还用了while循环(因为要测定多个DFA),所以一定要切记new完要自己去delete释放内存空间

如果一开始换用静态数组也没这些问题


展开阅读全文

没有更多推荐了,返回首页