图灵机UN*2

一.题目分析
题目要求:根据的图灵机的工作原理求出任意一个数的二倍数
题目分析:先将该数字由十进制转换成对应的二进制码,然后进行扩展。然后根据图灵机的工作原理对扩展二进制码进行计算,然后进行收缩,最后将普通二进制码转换成十进制码
二.算法构造
1.先将输入的十进制转换成对应的二进制码
2.根据图灵机的扩展规则将普通二进制代码进行扩展
规则:0->0
1->10
,(逗号)->110
然后在俩段加上无限个0(为了方便计算,将存放扩展二进制代码的第一个数组元素设置成0)
3.根据图灵机的计算规则,将扩展后的二进制代码进行计算
规则:内态 输入 改变后的内态 输出
0 0 -> 0 0 右移
0 1 -> 1 0 右移
1 0 -> 0 1 右移
1 1 -> 10 1 右移
10 0 -> 11 1 右移
11 0 -> 0 1 停机
4.将扩展后的二进制码进行收缩,从数组的第一位开始比较,如果第一位数组元素的值与相邻的数组元素值相等,那么只可能是00的情况了,将收缩的数组元素赋值为0,i++,下个元素与相邻的元素再进行比较。如果不相等就是10或01的情况,将收缩后的数组元素赋值为1,i=i+2,然后第i个数组元素再与相邻的元素进行比较。
5.将收缩后的二进制代码转换成十进制,输出
三.算法实现
程序源代码:
package turing1;
import java.util.Scanner;//导包
public class Turing1 {
public static void main(String[] args)
{
int[] farray= new int[15];//用来存放扩展前的二进制码
int[] sarray= new int[30];//用来存放扩展后的二进制码
int[] tarray= new int[15];//用来存放收缩后的二进制码
Scanner sc=new Scanner(System.in);//创建键盘录入对象
System.out.println(“请输入要计算的数字”);
int input=sc.nextInt();
//将十进制的数先转换成二进制数,然后转换成扩展后的二进制码
int flength=CreatBinary(input,farray,sarray);
//根据图灵机的转换规则,将扩展后的二进制码进行计算
int tlength=Stransform(flength,sarray);
//将扩展后的二进制码转换成普通的二进制码,然后转换成十进制码
Shrink(tlength,sarray,tarray);
}

//将十进制的数先转换成二进制数,然后转换成扩展后的二进制码
public static int CreatBinary(int input,int farray[],int sarray[])
{
	int i=0;//用来存放二进制码的长度
	//将十进制数转换成二进制数
	while(input!=0)
	{
		farray[i]=input%2;//通过取余和整除的方法求出二进制码
		input/=2;
		i++;
	}
	for(int j=0;j<i/2;j++)//将二进制码逆序排列
	{
		int temp=farray[j];
		farray[j]=farray[i-j-1];
		farray[i-j-1]=temp;
	}
	//将二进制码进行扩展
	int k=1;//从下标为1的数组开始计算,下标为0数组的设置为0
	for(int j=0;j<i;j++)
	{
		//扩展规则:0->0,1->10,逗号->110
		if(farray[j]==1)
		{
			sarray[k]=1;
			sarray[k+1]=0;
			k+=2;
		}
		else
		{
			k++;
		}
	}
	sarray[k]=1;
	sarray[k+1]=1;
	sarray[k+2]=0;
	k+=3;
	System.out.print("这个数字的扩展二进码是:");
	for(int j=0;j<k;j++)
		System.out.print(sarray[j]);
	System.out.println(" ");
	return k;
}

//根据图灵机的转换规则,将扩展后的二进制码进行计算
public static int Stransform(int k,int sarray[])
{int flag=0;//表示图灵机的内态
for(int j=0;j<=k;j++)//图灵机的转换规则
{
	if(flag==0&&sarray[j]==0)//0 0 -> 0 0 R
	{
		sarray[j]=0;
		System.out.println("内态由 0 变成 0,输入为 0 ,输出为 0 ,右移");
	}
	else if(flag==0&&sarray[j]==1)//0 1-> 1 0 R 
	{
		sarray[j]=0;
		flag=1;
		System.out.println("内态由 0 变成 1,输入为 1,输出为 0,右移");
	}
	else if(flag==1&&sarray[j]==0)// 1 0 -> 0 1 R
	{
		sarray[j]=1;
		flag=0;
		System.out.println("内态由 1 变成 0,输入为 0 ,输出为 1,右移");
	}
	else if(flag==1&&sarray[j]==1)// 1 1-> 10 0 R
	{
		flag=10;
		sarray[j]=0;
		System.out.println("内态由 1 变成 10,输入为 1 ,输出为 0 ,右移");
	}
	else if(flag==10&&sarray[j]==0)// 10 0 -> 11 1 R
	{
		flag=11;
		sarray[j]=1;
		System.out.println("内态由 10 变成11,输入为 0 ,输出为 1 ,右移");
	}
	else// 11 0 -> 0 1 STOP
	{
		flag=0;
		sarray[j]=1;
		System.out.println("内态由 11 变成 0,输入为 0 ,输出为 1 ,停机");
		break;
	}
}
System.out.print("计算以后的扩展二进码为:");
k+=2;
for(int j=0;j<k;j++)
	System.out.print(sarray[j]);
return k;
	
}

//将扩展后的二进制码转换成普通的二进制码,然后转换成十进制
public static void Shrink(int k,int sarray[],int tarray[])
{
	int m=0,n=0;
	while(m<k-4)//由于最后三位是110,表示逗号,所以不考虑
	{
		if(sarray[m]==sarray[m+1])//如果相邻的俩个数相等,一定是00的情况
		{
			tarray[n]=0;//对应普通的二进制码就是0
			n++;
			m++;
		}
		else//如果相邻的俩个数不想等,一定时10或01的情况
		{
			tarray[n]=1;//对应的普通二进制码就是1
			n++;
			m=m+2;
		}
	}
	System.out.println(" ");
	System.out.print("收缩以后的二进制码为:");
	for(int j=0;j<n;j++)
		System.out.print(tarray[j]);
	int output=0;//输出结果
	int leap=1;//二进制的位数
	for(int j=n-1;j>-1;j--)
	{
		if(tarray[j]==1)
		{
			output+=leap;
			leap*=2;
		}
		else
			leap*=2;
	}
	System.out.println(" ");
	System.out.println("计算结果为:"+output);
}

}
四.调试、测试及运行结果
调试:
一开始在对扩展二进制码进行计算的时候为了方便,直接采用6个ify语句进行计算,结果发生了错误
在这里插入图片描述

结果显示:
在这里插入图片描述

发现错误后将6个if语句写成了if语句的嵌套,最后扩展正确
测试:
1.测试输入一个任意十进制的数字将其装换成二进制码,然后根据图灵机的扩展规则得到相应的扩展二进制码
在这里插入图片描述

调试结果:
在这里插入图片描述

2.测试将扩展后的二进制代码通过图灵机计算的规则进行计算

在这里插入图片描述

在这里插入图片描述

测试结果:
在这里插入图片描述

3.测试将计算计算后的二进制码收缩成普通二进制码,最后转换成十进制数
在这里插入图片描述
在这里插入图片描述

测试结果:

在这里插入图片描述

运算结果:
1.输入5
结果为:
在这里插入图片描述

2.输入11
结果为:

在这里插入图片描述

3.输入34
结果为:

在这里插入图片描述

五.经验归纳
1.在解决一个问题的是时候,先不要忙的编程序。首先在计算本上先举一些具体的例子来验证自己的想法是否正确。如果有错误,应该认真的改正
2.在编写程序的过程中,如果遇到一些思路上难以理解的东西,多于其他同学进行讨论,说不定在讨论的过程中,就会明白问题的本质
3.在编写程序的时候,千万不能投机取巧从而省略一些步骤。例如在计算扩展二进制码的时候,为了简单,直接用若干个if。最后还是改成了if的嵌套,浪费了大把的时间。
4.更加体会到了在编写程序的过程中,写注释的一些好处

猜你喜欢

转载自blog.csdn.net/weixin_44382383/article/details/88750897