一.实验题目
模拟图灵机(XN×2)的运行过程
二.实验内容
对于任意给定的一台Turing机和任意给定的字符串w ( w不含空格),编程模拟此Turing机的运行过程,要求输出从开始运行起的每一步骤的结果。
三.算法构造
1.根据提示输入一个十进制整数
2.将十进制数转换成二进制数
a.定义一个数组来存储转换结果
b.循环将整数进行除2取余数,余数存储到数组中。
c.当整数整除为0时,结束循环
d.逆序输出数组,得到转换结果
3.将转换成的二进制数扩展成图灵机磁带上的数
a.定义一个数组来存储扩展后的结果
b.新数组的第一个数为0
c.遍历二进制数组,值为1时,新数组往后补10;值为0时,新数组往后补0
d.在新数组后补逗号110e.输出新数组,得到扩展后的二进制
4.输出图灵机执行指令的运行过程
a.定义一个数组存储内态和输入值
b.遍历扩展后的二进制数组,判断内态和输入值
*内态为0,输入为0时,内态和输入值不变,右移,输出输入值
*内态为0,输入为1时,内态变为1,输入值变为0,右移,输出输入值
*内态为1,输入为0时,内态变为0,输入值变为1,右移,输出输入值
*内态为1,输入为1时,内态变为10,输入值变为0,右移,输出输入值
*内态为10,输入为0时,内态变为11,输入值变为1,右移,输出输入值
* 内态为11,输入为0时,内态变为0,输入值变为1,停止,输出输入
5. 输出执行指令后的二进制
a.定义一个新数组来存储执行指令后的二进制
b. 在4的输出值后加逗号110
c. 输出新数组,得到执行指令后的二进制
6. 缩进二进制并输出
a. 定义一个新数组来存储缩进后的二进制
b. 遍历删除逗号的执行指令后的二进制
*为1或下一位为1时,输出1
*否则输出0
c. 输出新数组,得到缩进后的二进制
7.将得到的二进制数转换成十进制数
四.算法实现
#include<stdio.h>
#include<math.h>
int main()
{
int n,i=0,e=0,m=0;
int a[100];
int b[1000];
int c[1];
int d[100];
printf("**********图灵机(XN×2)**********\n");
printf("请输入一个十进制整数:\n");
scanf("%d",&n);
//十进制转换成二进制
while(n!=0)
{
a[i]=n%2;
n=n/2;
++i;
}
printf("转换成二进制为:\n");
int sum1=0;
for(i=i-1;i>=0;i--)
{
printf("%d",a[i]);
++sum1;//二进制数数组长度
}
printf("\n");
b[0]=0;
int j=1,sum2=1;
//二进制扩展
for(i=sum1-1;i>=0;i--)
{
switch(a[i])
{
case 1:
{
b[j]=1;
b[j+1]=0;
j+=2;
sum2+=2 ;
}
break;
case 0:
{
b[j]=0;
j+=1;
sum2+=1;
}
break;
}
}
//逗号
b[j++]=1;
b[j++]=1;
b[j++]=0;
sum2=sum2+3;
printf("扩展后的二进制为:\n");
//输出扩展后的数组
for(j=0;j<sum2;j++)
{
printf("%d",b[j]);
}
printf("\n");
c[0]=0;//内态值
printf("执行指令的运行过程:\n");
for(j=0;j<sum2-1;j++)
{
c[1]=b[j];//输入值
if((c[0]==0)&&(c[1]==0))//内态为0,输入为0时,内态和输入值不变,右移
{
c[0]=0;
b[j]=0;
printf("%d ",b[j]);
}
else if((c[0]==0)&&(c[1]==1))//内态为0,输入为1时,内态变为1,输入值变为0,右移
{
c[0]=1;
b[j]=0;
printf("%d ",b[j]);
}
else if((c[0]==1)&&(c[1]==0))//内态为1,输入为0时,内态变为0,输入值变为1,右移
{
c[0]=0;
b[j]=1;
printf("%d ",b[j]);
}
else if((c[0]==1)&&(c[1]==1))//内态为1,输入为1时,内态变为10,输入值变为0,右移
{
c[0]=10;
b[j]=0;
printf("%d ",b[j]);
}
else if((c[0]==10)&&(c[1]==0))//内态为10,输入为0时,内态变为11,输入值变为1,右移
{
c[0]=11;
b[j]=1;
printf("%d ",b[j]);
}
else if((c[0]==11)&&(c[1]==0))//内态为11,输入为0时,内态变为0,输入值变为1,停止
{
c[0]=0;
b[j]=1;
break;
printf("%d ",b[j]);
}
}
//逗号
b[j++]=1;
b[j++]=1;
b[j++]=0;
printf("\n执行指令后的结果为:\n");
for(int k=0;k<j;k++)
{
printf("%d",b[k]);
}
printf("\n缩进后的结果为:\n");
for(int k=0;k<j-3;e++)
{
if(b[k]==1||b[k+1]==1)
{
d[e]=1;
k+=2;
}
else
{
d[e]=0;
k+=1;
}
}
//输出缩进后的二进制
for(int k=0;k<e-1;k++)
printf("%d",d[k]);
//二进制转换成十进制
for(int k=0;k<e-1;k++)
{
if(d[k]-0==1)
m=m+pow(2,e-2-k);
}
printf("\n转换成十进制为:\n%d",m);
}
五.调试、测试及运行结果
- 调试截图
2. 测试截图
六.实验心得
刚开始写的时候没有一点头绪,只写了十进制到二进制的转换,再加上对图灵机的指令执行了解的不是很清楚,就不知道怎样开始,后来和室友交流了很久,渐渐地开始有了构思。
从刚开始的二进制数以整数输出转换到将其存储在数组中输出,从扩展二进制到缩进二进制,我遇到了很多问题,也存在了很多问题,刚开始是算法写的有错误,改了很久后才发现遍历数组时for循环中对数组长度的控制也存在着错误,琢磨了很久才将扩展的二进制写正确。对于缩进,由于自己对0和1的位置分布考虑不周,也出现了缩进错误的问题,好在和室友认真讨论了后将其补充完整,最后完成了代码,也实现了对图灵机乘法的模拟。
由于自己能力不足,写代码耗费了很长的时间,希望通过不断地练习能提高自己写代码的效率和质量。