作者:无*
时间:2019-3-20
一.题目分析:
1.利用图灵机的概念和基本结构,执行XN*2的指令并输出相应结果。
2.首先,输入的数为一个十进制的数字,通过转化函数将十进制转化为二进制,并将二进制存入相应的数组中。
3.将二进制数利用扩展原理,所得的相应序列即为扩展后的序列。
4.将扩展后的序列,利用图灵机的指令原理,用if ,else if语句写出来(此处共六条指令)。
5.要注意的是,在序列执行指令还没有到达STOP时,但相应序列已经遍历完成,这是需要定义一个标志,通过标志完成相应的“补0”。
6.最后通过收缩序列得到所要求的结果。
二.算法构造:
1.第一步要进行的是二进制的转化,接着对所得的二进制数进行扩展,利用了0->0;1->10 ; ,(逗号)->110;把二进制数放入数组中,最后得到扩展后的序列。
例如:1.十进制数3 转化为二进制数11 扩展后序列01010110(110为逗号)
2.扩展的序列再进行6条相关指令的执行
00->00R; 01->10R; 10->01R;
11->100R; 100>111R; 110->01STOP;
3.执行相关6条指令
4.对序列进行相应的“补零”,停止指令 110->01STOP
在此处添加标志以便于进行补零
5.对序列进行缩进并输出。
6.将二进制序列转化为十进制并输出
例如:.十进制数3 转化为二进制数11 扩展后序列01010110(110为逗号)
第一步 01010110 内态为0,输入为零执行00->00R;
第二步 01010110 内态为0,输入为1,执行 01->10R;将当前1变为0
第三步 00010110 内态为1,输入为0,执行10->01R;将当前0变为1
第四步 00110110 内态为0,输入为1,执行01->10R;将当前1变为0
第五步 00100110 内态为1,输入为0,执行10->01R;将当前0变为1
第六步 00101110 内态为0,输入为1,执行01->10R;将当前1变为0
第七步 00101010 内态为1,输入为1,执行11->100R;将当前1变为0
第八步 00101000 内态为10,输入为0,执行100>111R;将当前0变为1,向后补零继续进行
第九步 001010010 内态为11,输入为0,执行110->01STOP;将当前0变为1
第十步 0010100110 停止
收缩后的序列即为110,转换为十进制即为6
由此可得到XN*2的编写过程
三.算法实现
#include"stdio.h"
#include"math.h"
#include"string.h"
int main( )
{ int n,m,j,a[100],bu=1;
int ki=0,chang=0;
printf("輸入数字");
scanf("%d",&n);
//转化二进制
while(n!=0)
{ j=n%2;
a[++ki]=j;
n=n/2;
chang++;
}
printf("转化为二进制为:\n");
//輸出二进制数
for(;ki>0;ki--)
{printf("%d",a[ki]);
}
int b[100];
int k;
b[0]=0; //定义新的数组,存入扩展后的序列
int len=0,i=1; //len为新数组的长度,初始值为0
printf("\n");
//进行扩展
for( k=chang;k>0;k--) //扩展原理 0->0; 1->10;
{ if(a[k]==1)
{ b[i]=1; b[i+1]=0; i+=2; len+=2;}
else{b[i]=0; i++; len+=1;}
}
printf("扩展后序列为:\n");
b[len+1]=1; b[len+2]=1; b[len+3]=0; //加逗号,在数组后面直接加
for(k=0;k<len+4;k++)
{ printf("%d",b[k]);}
printf("\n");
//输出新数组元素,即为扩展后的序列
//执行相关指令
int nei=0;
m=len+4;
while(bu)
{ b[m]=0;
for(k=0;k<m+1;k++) //6条指令
{
if(b[k]==0&&nei==0)
{ b[k]=0; nei=0;}
else if(nei==0&&b[k]==1)
{nei=1; b[k]=0;}
else if(nei==1&&b[k]==0)
{nei=0; b[k]=1;}
else if(nei==1&&b[k]==1)
{nei=10; b[k]=0;}
else if(nei==10&&b[k]==0)
{nei=11; b[k]=1;}
else if(nei==11&&b[k]==0)
{nei=0; b[k]=1; bu=0; break;} // bu在此处为标志
}
m++;
}
b[m]=0;
printf("XN*2的结果为\n");
for(k=0;k<m+1;k++)
{ printf("%d",b[k]);}
printf("\n");
//缩进后的序列
int c[100];
int q=0;
printf("收缩后的序列为:\n");
for(k=0;k<m-2;)
{ if((b[k]==0&&b[k+1]==1)||(b[k]==1&&b[k+1]==0))
{ c[q]=1; k=k+2; q++; }
else
{c[q]=0; k++; q++;}
}
m=q-1;
for(k=0;k<m;k++)
{ printf("%d",c[k]);}
printf("\n");
//转化为十进制并输出
int term1,term2,sum=0;
for(k=0;k<m;k++)
{ term1=1;
if(c[k]==1)
{for(term2=1;term2<m-k;term2++)
term1*=2;
sum+=term1;
}
}
printf("转化为十进制数为:\n");
printf("%d\n",sum);
return 0;
}
四.调试,测试及运行结果
1.调试:
2.测试:
(1)此处为十进制转二进制测试代码
(2)序列进行扩展
(3)计算XN*2的结果
(4)对序列进行收缩
(5)输出十进制数
3.运行结果:
此处分别对两个数进行测试,所得结果均为XN×2.
五.经验归纳
此次上机实验,首先要对图灵机有一定的掌握,掌握图灵机的相关指令,可以通过举一些例子进行论述,最后再将每个模块用代码编写出来。要注意的是,补零是最重要的,否则序列将无法输完;其次,还应该注意指令的运行,内态和输入态分别是什么,该执行哪一条指令;并学会运用数组进行相关计算。
心得:
在这次编程过程中,还是遇到了许多问题,比如说:数组长度的改变,逆序的输出,指令执行不正确等问题,在解决这些问题的同时,又对一些细小的知识进行了巩固,掌握了图灵机的原理,总之,这次编程还是很有收获的。