第二章 图灵机
一、实验目的
1.掌握图灵机的概念和基本结构,理解图灵机的基本指令和编码方式;
2.掌握图灵机的编程方法。
二、实验内容
对于任意给定的一台Turing机和任意给定的字符串w ( w不含空格),编程模拟此Turing机的运行过程,要求输出从开始运行起的每一步骤的结果。
三、算法构造:
图灵机在扩展二进制位实现(XN*2)的运算指令:
00→00R,
01→10R,
10→01R,
11→100R,
100→111R,
110→01STOP。
四、程序实现
/*此程序是用来模拟图灵机XN*2的过程
要求是输入一个已经扩展好的的二进制数
输出打印图灵机的每一位的指令步骤*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char a[100000];//定义一个足够大的数组
int length;//定义数组的长度
int i=0,*p;
int flag=0;//内态
printf("请输入一个已经扩展好的二进制数字(前后可以多加好些0):");
scanf("%s",&a);//输入数组数据
length=strlen(a);//求数组长度
//printf("%s",a);
// for(i=0;i<N;i++)
// printf("a[%d]=%d\t",i,a[N]);
for(i=0;i<=length;i++)
{
if(flag==0&&a[i]=='0')//指令00->00R,即当内态为0,输入为0时
{
a[i]='0';
flag=0; //新的内态为0,输出为0
}
else if(flag==0&&a[i]=='1') //01->10R,即当内态为0,输入为1时
{
a[i]='0';
flag=1; //新的内态为1,输出为0
}
else if(flag==1&&a[i]=='0') //10->01R,即当内态为1,输入为 0时
{
a[i]='1';
flag=0; //新的内态为0,输出为1
}
else if(flag==1&&a[i]=='1') //11->100R,即当内态为1,输入为1时
{
a[i]='0';
flag=10; //新的内态为10,输出为0
}
else if(flag==10&&a[i]=='0') //100->111R,即当内态为10,输入为0时
{
a[i]='1';
flag=11; //新的内态为11,输出为1
}
else if(flag==11&&a[i]=='0') //110->01STOP,即当内态为11,输入为0时
{
a[i]='1';
flag=0; //新的内态为0,输出为1
}
printf("%s\n",a); //每计算一次,打印一次结果
}
// for(i=0;i<N;i++)
// printf("a[%d]=%d\t",i,a[i]);
system("pause");
return 0;
}
【测试截图】
【调试截图】
测试的时候我输入的是3的二进制扩展位,由于这个代码不会自动补零,所以测试的这个结果我也无法判定它是否正确,在之后的测试中我在末尾多输入了几个零,发现最终结果是有问题的,正确结果应该是0010100110,但是最终结果却是0010100100,于是经过调试,发现是最后一条语句的break有问题,应该去掉,去掉结果终于正确了。
【运行结果】
五、归纳总结
模拟图灵机的这次实验,有很难的地方,我们在课堂上学习如何将一个十进制的数转换成二进制,进而扩展,在课堂我虽然写的很慢,但是至少在最后可以得出结果,但是到了编程这,于我而言,就变成了一件只可意会不可言传不可言传的事了,十进制转换成二进制还好,但是扩展我真的是心有余而力不足,因此,我这次的模拟图灵机直接输入的已经扩展好的数字,虽然没能完成那个部分,但是这次编程对我来说依旧有收获:
(1)我一开始一直定义的是int变量,在输入的时候遇到的困难,定义数组大小时也出现了问题,经过思考,最后我还是用了char,字符型变量,学会如何定义字符数组,如何输入输出字符串数组。不过在引用和改变其数值的时候一度忘记加上单引号’’导致程序一直有问题,而且应该要使用%s来输出最后的字符串。
(2)在将最后一个命令语句翻译时,我添加了break,作为结尾停止,但是所得的结果一直都不正确,经过调试,将其删除,终于可以得到正确结果。
(3)这次的上机实践让我一度很惆怅,因为这种无力感真的太不好了,但是这也让我认识到了自己还有很多很多不足的地方,我一定会好好努力,多和老师同学交流学习,提升自己的。