模拟图灵机进行UN+1

一、题目分析
对于任意给定的一台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可以给输入的字符串足够的空间,否则不能进行后续操作。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值