一、题目分析
对于任意给定的一台Turing机和任意给定的字符串w ( w不含空格),编程模拟此Turing机的运行过程,要求输出从开始运行起的每一步骤的结果。因此,我们模拟图灵机进行UN+1操作。
二、算法构造
UN+1的四个指令是00—>00R,01—>11R,10—>01STOP,11—>11R。它简单地把1加到一个一进位数上。仪器在开始时处于内态0并且读到0.根据第一条指令,它仍保留为0,向右移动一格,而且停在内态0上,在它遇到第一个1之前,它不断地向右移动。然后第二条指令开始作用:它把1留下来不变而且再向右移动,但是现在处在内态1上。根据第四条指令,它停在内态1上,不改变这些1,一直向右移动,一直达到跟在这些1后面的第一个0为止。第三条指令接着告诉它把那个0改变成1,向右再移动一步(STOP是表示R和STOP),然后停机。这样,另一个1已经加到这一串1上。
在进行UN+1的操作中,可以必要性地设定一个内态标志flag,输入已扩展的二进制字符串,这个字符串不能超过所定义的数组的长度。再通过if—else语句根据四条指令控制内态、输入和输出。
附加:为了使程序细化且功能更加强大,尝试了先输入一个十进制数,再将十进制数转化为二进制数,进而对二进制数进行扩展,再根据四条指令进行操作即可得到UN+1。
三、算法实现
#include <iostream>
using namespace std;
#include <string.h>
#include <stdlib.h>
int main()
{
char arr[20];
int i, len; //len是字符数组的长度
int flag = 0; //flag是内部状态,初始化内部状态
printf("请输入已扩展的二进制字符串:");
//gets_s(arr);
scanf_s("%s", arr,20);//20可以给输入的字符串足够的空间
len = strlen(arr); //计算字符数组的长度
for (i = 0; i <= len; i++)
{
if (flag == 0 && arr[i] == '0') //00→00R
{
flag = 0;
arr[i] = '0';
printf("指令1:%s\n", arr);
}
if (flag == 0 && arr[i] == '1') //01→11R
{
flag = 1;
arr[i] = '1';
printf("指令2:%s\n", arr);
}
if (flag == 1 && arr[i] == '0') //10→01STOP
{
flag = 0;
arr[i] = '1';
printf("指令3:%s\n", arr);
break;
}
if (flag == 1 && arr[i] == '1') //11→11R
{
arr[i] = '1';
printf("指令4:%s\n", arr);
}
}
printf(" UN+1的结果是 %s\n", arr);
system("pause");
return 0;
}
return b;
}
附加:
//将十进制数转化为二进制数
int Change()
{
int i = 0, x = 0;
int ar[30];
int k, j, temp;
printf("请输入一位十进制数");
scanf("%d", &x);
while (x > 0)
{
temp = x % 2;
ar[i++] = temp;
x = x / 2;
}
k = i;
printf("转化为二进制数:\n");
for (j = 0; j < k; j++)
{
if (i > 0)
{
ar[j] = ar[--i];
printf("%d", ar[j]);
}
}
printf("\n");
}
//对二进制数进行扩展
int * Expand(int ar[])
{ int cnt1=0;
int b[50];
int length=strlen(ar);
for(int i=0;i<length;i++)
{
if(ar[i]==1){
b[cnt1++]=1;
b[cnt1++]=0;
}
else if (ar[i]==0)
{ b[cnt1++]=0;
}
else {
b[cnt1++]=1;
b[cnt1++]=1;
b[cnt1++]=0;
break;
}
}
return b;
}
四、调试及测试
实行UN+1操作时,需要将字符串存入数组中,在VS2017这个编译环境下,当存入字符串时,会有如下语句;scanf("%s", arr,);会出现如下错误:
可将语句改为:scanf_s("%s", arr,);但还会出现如下错误:
此时无法进行后续指令显示操作,故应为:scanf_s("%s", arr,20);//20可以给输入的字符串足够的空间
最后经过编译,编译无错:
五、运行结果
附加:
十进制数转化为二进制数:
六、经验归纳
在模拟图灵机进行UN+1的操作中,可以设定一个内态标志flag,输入已扩展的二进制字符串,这个字符串不能超过所定义的数组的长度。再通过if—else语句根据四条指令控制内态、输入和输出。
为了使程序细化且功能更加强大,尝试了先输入一个十进制数,再将十进制数转化为二进制数,进而对二进制数进行扩展,再根据四条指令进行操作即可得到UN+1。在十进制数转为二进制数过程中可以完成此操作,但是我不能完成对二进制数进行扩展的函数中对二进制数的传入,这里应该借助指针来完成,这正体现了知识漏洞。
UN+1操作需要将字符串存入数组中,在VS2017这个编译环境下,需要scanf_s("%s", arr,20);//20可以给输入的字符串足够的空间,否则不能进行后续操作。