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