- 题目分析
本次实验模仿图灵机的计算过程,要求对于任意给定的一台Turing机和任意给定的字符串w ( w不含空格),编程模拟此Turing机的运行过程,要求输出从开始运行起的每一步骤的结果。本次实验我选择了UNx2图灵机,编程主要有一下几个步骤,一是输入十进制正整数转化为二进制再转化为扩展二进制存入数组,二是用程序设计语言描述图灵机内部指令,处理得到的扩展二进制串,最后把结果转化回十进制输出。
2.算法构造
在此论证算法设计中的一些必要的设计依据。模拟这个图灵机,首先要把输入的十进制数转化为二进制,算法为连续取这个数除以2的余数,倒序存入数组即可,然后是转化为扩展二进制,根据扩展规则0存0,1存10,存完二进制位后在后面加上110即转换完成,接下来是对数组的操作,根据指令集转化为c++语句即可,构建永真循环写入语句指令,图灵机的纸带即待操作的数组,通过指针对数组进行操作模仿图灵机针头在纸带上的移动,读写数组即实现了针头对纸带上数据的改写,在循环里设置结束语句保证图灵机能停机并输出结果。最后把得到的结果以相同的扩展规则收缩为二进制在转化为十进制输出即完成了图灵机的过程模拟。
3.算法实现
#include<iostream>
using namespace std;
class touring//定义一个touring类,包含存输入值得成员变量,存扩展二进制的数组,将输入得数转化为二进制的成员函数
{
private:
int input;//存输入的数
int data[100] = {0};//存扩展二进制
public:
touring(int x,int y)
{
input = x;
}
int * binary() ;//扩展二进制转化函数
void imitate(int *) ;//过程模拟函数,对每一步操作都输出
void result();//输出结果
};
void main()
{
int x, y = 0;
cout << "输入一个整数" << endl;
cin >> x;
touring unx2(x, y);
unx2.imitate(unx2.binary());
unx2.result();
system("pause");
}
int *touring::binary()
{
int m[20] = { 0 }, n[20] = {0};//定义两个数组,一个存正序二进制,一个存逆序二进制
int *p=data;
int i(0), j,k(0);
//求出二进制
while (1)
{
m[i++] = input % 2;//把输入的数据的二进制逆序存入数组m[]
input = input / 2;
if (input == 0)
break;
}
for (j = i - 1;j >= 0;j--)
{
n[k++] = m[j];//存入正序二进制
}
k = 0;
cout << "二进制:";
for (j = 0;j < i;j++)
{
cout << n[j];
}
cout << endl;
//求出扩展二进制
for (j=0;j<i;j++)
{
if (n[j] == 0)
data[k++] = 0;
else
{
data[k++] = 1;
data[k++] = 0;
}
}
data[k] = 1;//将结束标示串110存入数组
data[k + 1] = 1;
data[k+ 2] = 0;
data[k+ 3] = 0;
data[k + 4] = 0;
cout << "扩展二进制:";
for(i = 0;i < k+ 5; i++)
{
cout << data[i];
}
cout << endl;
return p;
}
void touring::imitate(int *p)//过程模拟
{
int indata = 0;
int flag;
if (input < 100)
flag= 15;
else flag = 20;
int i=0 ;
while (1)
{
if (*p == 0 && indata == 0)
{
cout << 0 << " " << 0 << "->" << 0 << " " << 0 << "R" << endl;//执行00->00R
do
{
cout << data[i++];
} while (i < flag);
cout << endl;
i = 0;
p++;
}
if (indata == 0 && *p == 1)//执行01->10R
{
cout << 0 << " " << 1 << "->" << 1 << " " << 0 << "R" << endl;
indata = 1;
*p = 0;
p++;
do
{
cout << data[i++];
} while (i < flag);
i = 0;
cout << endl;
}
if (indata == 1 && *p == 0)//执行10->01R
{
cout << 1 << " " << 0 << "->" << 0 << " " << 1 << "R" << endl;
indata = 0;
*p = 1;
p++;
do
{
cout << data[i++];
} while (i < flag);
i = 0;
cout << endl;
}
if (indata == 1 && *p == 1)//执行1 1->10 0R
{
cout << 1 << " " << 1 << "->" << 10 << " " << 0 << "R" << endl;
indata = 10;
*p = 0;
p++;
do
{
cout << data[i++];
} while (i < flag);
i = 0;
cout << endl;
}
if (indata == 10 && *p == 0)//执行10 0->11 1R
{
cout << 10 << " " << 0 << "->" << 11 << " " << 1 << "R" << endl;
indata = 11;
*p = 1;
p++;
do
{
cout << data[i++];
} while (i < flag);
i = 0;
cout << endl;
}
if (indata == 11 && *p == 0)//执行11 0->01STOP
{
cout << 11 << " " << 0 << "->" << 0 << " " << 1 << "STOP" << endl;
indata = 0;
*p = 1;
do
{
cout << data[i++];
} while (i < flag);
i = 0;
cout << endl;
break;
}
}
}
void touring::result()//输出十进制结果
{
int r[10] = { 0 };
int *p = data;
int i = 0, k = 0;
int sum = 0;
while (1)
{
if (*p == 0)
{
r[i] = 0;
i++;
p++;
}
else
if (*(p + 1) == 0)
{
r[i] = 1;
p = p + 2;
i++;
}
else
{
break;
}
}
int j;
for ( j = i-1; j >= 0;j--)
{
sum += (r[j] * pow(2, k++));
}
cout << "结果:" << sum << endl;
}
4.调试、测试及运行结果
测试二进制转换
void main()
{
int x;
cin >> x;
touring test(x);
test.binary();
system(“pause”);
}
测试过程模拟
void main()
{
int x;
cin >> x;
touring test(x);
test.imitate(test.binary());
system("pause");
}
功能正常,程序运行结果:
5.经验归纳
图灵机通过一个假想模型将可计算数学问题机械化,通过假想的纸带以合适的存储形式存入数据,在假想的机器里存入指令集,指令集包含对数据的读写,针头的移动判断两类,指令通过假想的针头对纸带上的数据进行读写操作,这样就实现了使机器能够自己判断接下来干什么,这次用C++编程模拟图灵机运行过程,总体感觉有点冗杂,和其他人交流了一下,有用java写,用pyhon写,似乎比用C++容易,肯定还有可改进的地方,编写过程没什么大问题,只是在运用指针时应该注意用的时候指针所指的位置,不然很容易出错。