图灵机命令

图灵机XN*2命令的执行

1. 题目分析
本次实验主要内容是模仿图灵机执行 XN2命令时的操作。
① 先设置一个变量in给其初值0,存储图灵机内态。并设置一维数组a[MAX],用于存储输入的十进制化为的二进制,应为不清楚输入的数具体化为了几位二进制数,需注意数组存储量MAX应该足够大。
② 设置一个一维数组b[MAX]放置扩展后的二进制代码,扩展具体思路是运用循环结构依次读取a[MAX]中元素的值,若读取元素为字符1,将其扩展为 01存到数组b[MAX]中,若读取元素为字符0,则将0存到字符数组中去。
③ 在执行图灵机XN
2命令时,用switch嵌套结构进行选择(外层选择结构输入的二进制代码a[MAX]进行选择,内层对内态in进行选择)。
④ 图灵机停止运行命令是(110->01STOP),所以需要设置一个停止标志,在满足停止标志时停止命令。
⑤ 设置一个一维数组从c[MAX]用于放置缩进代码,缩进具体思路是运用循环结构遍历数组b[MAX],当数组相邻元素为01或者10时,缩进为1,当相邻元素为00时,缩进为0。最后将二进制化为10进制输出。
2. 算法构造
① 设置三个一维数组分别放置由十进制转化的二进制代码,进行扩张后的二进制代码,以及执行命令后缩进的二进制代码。
② 十进制转化二进制算法:输入十进制数x,x除以二的余数如果是1,那么此次循环存到数组a[MAX]的元素为字符1,反之为字符0.最后x自除2.开始新的一轮循环直到x值为0;
③ 二进制扩展算法:将数组a[i]遍历输出,若读取元素为字符1,将其扩展为 01存到数组b[MAX]中,若读取元素为字符0,则将0存到字符数组中b[MAX]去。
④ 命令执行函数:此算法需注意一点,若命令将扩展后的二进制数组b[MAX]遍历完,但是还未能达到命令停止执行的标志,那就需要在扩展数组b[MAX]后续0,使其可以继续执行命令 ,直到停止命令的执行。
⑤ 二进制缩进算法:用循环结构遍历数组b[MAX],当数组相邻元素为01或者10时,缩进为1,当相邻元素为00时,缩进为0。最后将二进制化为10进制输出。
⑥ 二进制化为十进制算法:将存放最终缩进结果的数组c[MAX]依次遍历,若从某个元素c[i]等于字符1,那么对初值为1的变量m进行乘2运算(乘2的个数是数组总数减去i),z最后将每次乘2运算结果累加,则得到最终十进制的结果。
3. 算法实现

#include<stdio.h>
#define MAX 1024
int conmand(char b[],int n)    //执行命令XN*2
{int i=0,in=0,tag=1;
printf("执行命令UN*2的结果为:\n");
while(tag)         //当命令命令为110->01,图灵机停止工作
{
	b[n]='0';     //当图灵机运行到扩张后二进制的最后一位还没停止,应该给二进制代码后续0
	for(i=0;i<n+1;i++)
	{
		switch(b[i]){
		case '0':
			{
				switch(in){
				case 0:break;
				case 1:in=0;b[i]='1';break;
				case 10:in=11;b[i]='1';break;
				case 11:in=0;b[i]='1';tag=0;break;
				}
			}break;
		case '1':
			{
				switch(in){
				case 0:in=1;b[i]='0';break;
				case 1:in=10;b[i]='0';break;
				}
				
			}break;
		}
	}
	n++;
}
b[n]='0';
for(i=0;i<n+1;i++)
printf("%c",b[i]);
printf("\n");
return n;
}
void suojin(char b[],int n)
{int j=0,i=0,end=0;
char c[MAX];
for(i=0;i<n-2;j++)
{
	if((b[i]=='0'&&b[i+1]=='1')||(b[i]=='1'&&b[i+1]=='0'))//当执行完命令数组的相邻两位变为10或者01,缩进为1
	{c[j]='1';
	i+=2;}
    else 
	{c[j]='0';
	i++;}
}
n=j-1;
printf("缩进的结果为:\n");
for(i=0;i<n;i++)     //将缩进结果化为十进制数
{
	int m=1;
	printf("%c",c[i]);
	if(c[i]=='1')
	{
		for(j=1;j<n-i;j++)
			m*=2;
		end+=m;}
}
printf("\n最终结果为:");
printf("%d\n",end);
}
void main()
{char a[MAX],b[MAX];
int e,x;
int i=0,n=0,s=0;
printf("请输入一个十进制数:\n");
scanf("%d",&x);
while(x)     //产生的二进制代码是逆序的
{
	if(x%2==1)     //如果十进制数除以二余数是1,那么此位二进制代码是1;反之为0
		a[i]='1';
    else a[i]='0';
	i++;
	x/=2;
	n++;      //产生的二进制的位数
}
for(i=0;i<n/2;i++)  //将数组进行逆序成为二进制代码
{
	char temp=a[i];
	a[i]=a[n-i-1];
	a[n-i-1]=temp;
}
printf("转化为二进制结果为:\n");
for(i=0;i<n;i++)
printf("%c",a[i]);
printf("\n");
printf("扩展结果为:\n");
b[0]='0';e=1;      //将产生的二进制代码进行扩展
for(i=0;i<n;i++)
{switch(a[i]){    //如果a[i]是1,扩展为01,二进制位数增加1位;a[i]是0,扩展为0,二进制位数不变
	case '0':
		{b[e]='0';
		e++;
		s++;}break;
    case '1': 
		{s+=2;
        b[e]='1';
        b[e+1]='0';
        e+=2;}break;}
};
n=s+1;         //扩展后二进制代码总数
for(i=0;i<n;i++)
printf("%c",b[i]);
printf("\n");
b[n]='1';b[n+1]='1';  //为扩展后的二进制代码后面加110/,
b[n+2]='0';
n+=3;
n=conmand(b,n);  //调用执行命令函数conmand()
suojin(b,n);  //调用缩进函数suojin()
}
  1. 调试、测试及运行结果。
    ① 调试结果
    在这里插入图片描述

② 测试结果
十进制转化为二进制的测试:
在这里插入图片描述

扩展测试:
在这里插入图片描述

执行命令XN*2的测试:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
缩进测试:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
③ 运行结果

在这里插入图片描述
5. 经验归纳
1)错误分析:
本次实验主要内容是模仿图灵机执行 XN*2命令时的操作。我编写程序时遇到的困难如下:①设置一维数组a[MAX],用于存储输入的十进制化为的二进制,因为不清楚输入的数具体化为了几位二进制数,数组存储MAX不够大。②刚开始对二进制代码进行扩展时,没有弄清楚扩展规律,以至于扩张时出现错误。(1扩张为01,0不变)。③命令执行函数算法未注意一点,若命令将扩展后的二进制数组b[MAX]遍历完,但是还未能达到命令停止执行的标志,那就需要在扩展数组b[MAX]后续0,使其可以继续执行命令 ,直到停止命令的执行。④自己在十进制转换二进制时,未逆序,导致二进制代码错误,在改正后这些问题均已解决。
2)个人心得:
通过这次实验我得到的感悟是:遇到困难时的心态要平和,冷静地去查找问题并解决问题。注意知识的总结和积累。最近,其实不止是本次程序实验带给我的收获,就是作为一个合格的程序员,要注意对知识的积累和知识体系的梳理,每隔一段时间就应该对自己近期的工作有个小结和反思,只有这样,才能不断进步,因此,我在CSDN开通了自己的博客,关于本次实验写的知识点总结在里面都有。

猜你喜欢

转载自blog.csdn.net/weixin_43920565/article/details/88676174