-
题目分析
对于任意给定的一台Turing机和任意给定的字符串w ( w不含空格),编程模拟此Turing机的运行过程,要求输 出从开始运行起的每一步骤的结果。 -
算法构造
(1), 输入一个正整数XN(2),将输入的正整数转化为二进制,存在P[]中
(3),将p[]中的二进制转化为拓展二进位,存在t[]中
(4),模拟图灵机XN*2的指令
(5),将模拟后的拓展二进位转化为二进制,存在p[]中
(6),将p[]中的二进制转化为十进制
图灵机XN*2在拓展二进位上实现运算的指令:
0 0—>0 0R 0 1—>1 0R 1 0—>0 1R 1 1—>10 0R 10 0—>11 1R 11 0—>0 1STOP
3.算法实现
#include <iostream>
using namespace std; //Xn*2的图灵机
int BinarySystem(int z[],int p[],int x) //将输入的十进制数转换为二进制输入到数组p[]
{
int num=0; //数组下标
do
{
z[num++]= x % 2;
x= x / 2;
}
while (x != 0);
for(int i = 0; i <= num - 1; i++)
p[i]= z[num - 1 - i];
for(int j=0; j<=num-1; j++) //检测此处是否正确
printf("%d",p[j]);
printf("\n");
return num-1;
}
int Binarynumber(int p[],int t[],int num) //求扩展二进制,存在t[]中
{
t[0]= 0;
int step=1;
for(int j=0;j<=num;j++)
{
if(p[j] == 1)
t[step++]= p[j];
t[step++]= 0;
}
t[step++]=1;
t[step++]=1;
t[step]= 0;
for(int k=0; k<=step; k++) //检测此处是否正确
printf("%d",t[k]);
printf("\n");
return step+1; //记录拓展二进制的位数
}
int simulate_Turing(int t[],int count1) //模拟过程
{
int state=0,i=0,j=1;
int count=count1;
while(j)
{
if(state==0&&t[i]==0){
state=0;
t[i++]=0;}
else if(state==0&&t[i]==1){
state=1;
t[i++]=0;
}
else if(state==1&&t[i]==0){
state=0;
t[i++]=1;
}
else if(state==1&&t[i]==1){
state=10;
t[i++]=0;
}
else if(state==10&&t[i]==0){
state=11;
t[i++]=1;
}
else if(state==11&&t[i]==0){
state=0;
t[i++]=1;
j=0;
}
if(i>=count)
count++;
for(int k=0;k<count;k++)
printf("%d",t[k]);
printf("\n");
}
return i+1;
}
int convert_Algorism(int p[],int t[],int count2)//将模拟后的拓展编码转换为二进制,存放在p[]中
{
int m=0,n=0;
int result=0; //十进制结果
int leap=1; //二进制的位数
while(m<count2-4) //最后三位是110,表逗号,不考虑
{
if(t[m]==t[m+1]) //相邻的俩个数相等是00的情况
{
p[n]=0;
n++;
m++;
}
else //相邻的俩个数不相等是10或01的情况
{
p[n]=1;
n++;
m=m+2;
}
}
printf("\n");
printf("模拟后的二进制为:");
for(int i=1;i<n;i++)
printf("%d",p[i]);
printf("\n");
for(int j=n-1;j>-1;j--)
{
if(p[j]==1)
{
result+=leap;
leap*=2;
}
else
leap*=2;
}
return result;
}
int main() {
int x; // 模拟的数字
int z[40]={0};
int p[40]={0}; //存放二进制
int t[100]={0}; //存放拓展二进制
int num; //求二进制时候的标志位
int count1,count2;
int result; //使用图灵机模拟运算后的输出结果
printf("请输入一个正整数x:");
scanf("%d",&x);
printf("该数字的二进制为:");
num=BinarySystem(z,p,x); //返回数组下标
printf("拓展编码:");
count1=Binarynumber(p,t,num); //返回拓展二进位的数组下标
printf("图灵机运行过程模拟:\n");
count2=simulate_Turing(t,count1); //返回每个运算后拓展二进制的位数
result=convert_Algorism(p,t,count2);
printf("计算结果为:%d",result);
printf("\n");
system(“pause”);
return 0;
}
4.调试、测试及运行结果
调试:
在第一次设计的模拟图灵机的函数中,由于使用了for语句,多重循环和选择语句,程序最后崩掉了,无法按照设想来运行了
调试过程,给这个函数添加监视变量j,t[j],k,d[j]等。最后发现问题在k值上,运行后无法重新从1开始
最后还是没办法改正过来,只好推倒重来。再次测试没有问题
运行结果:
5.经验归纳
在对01串的处理中使用了数组,学会了传入地址,返回长度这样一种操作,其次,在调试错误的过程中,让我对错误处理又熟练了一些。还有就是,尽量写简单函数,不要嵌套一些复杂函数,使人难以理解。还有产品的迅速迭代是有必要的。最后,那个没有解决的问题,先放在这里吧。
/*
//struct date d[7];
struct date
{
int Internal_state1; //内态
int input; //输入
int Internal_state2; //内态
int output; //输出
};
void put_date(struct date d[])//指令集
{
d[1].Internal_state1= 0;
d[1].input= 0;
d[1].Internal_state2= 0;
d[1].output= 0;
d[2].Internal_state1= 0;
d[2].input= 1;
d[2].Internal_state2= 1;
d[2].output= 0;
d[3].Internal_state1= 1;
d[3].input= 0;
d[3].Internal_state2= 0;
d[3].output= 1;
d[4].Internal_state1= 1;
d[4].input= 1;
d[4].Internal_state2= 10;
d[4].output= 0;
d[5].Internal_state1= 10;
d[5].input= 0;
d[5].Internal_state2= 11;
d[5].output= 1;
d[6].Internal_state1= 11;
d[6].input= 0;
d[6].Internal_state2= 0;
d[6].output= 1;
}
int simulate_Turing(int t[],struct date d[],int count1) //模拟过程
{
int input;
int state=0; //初始条件下,内态为0
int p=1; //逻辑变量
int count=count1; //二进位数现在的长度记录
for(int j=0;p!=0; j++) //依次遍历 ,操作均在此语句下,
{
if(j>count)
count++;
input=t[j]; //得到每次的输入input;
for(int k=1;k<7;k++)
{
if((state == d[k].Internal_state1) && (input == d[k].input))
{
state= d[k].Internal_state2; //将state2赋值给state
t[j]= d[k].output; //将output赋值给t[j];
for(int z= 0; z<10;z++)
printf("%d",t[z]);
printf("\n");
if(6==k)
{
p=0;
break;
}
}
}
}
return 0;
}
*/