1.问题描述
对于XN+1或XN*2图灵机进行模拟,任意给定的十进制数a,转换为收缩扩展二进制的编码,再编程模拟此Turing机的运行过程,要求输出从开始运行起的每一步骤的结果。 用C或C++或java或python语言实现程序解决问题。
2.问题分析
(1)扩展二进制编码转换规则:
① 0→0;
② 1→10;
③ , →110;
(2)图灵机(XN*2)在拓展二进位上的指令:
④ 内态为0,输入为0→内态为0,输出为0,右移;
⑤ 内态为0,输入为1→内态为1,输出为0,右移;
⑥ 内态为1,输入为0→内态为0,输出为1,右移;
⑦ 内态为1,输入为1→内态为10,输出为0,右移;
⑧ 内态为10,输入为0→内态为11,输出为1,右移;
⑨ 内态为11,输入为0→内态为0,输出为1,STOP;
3.概要设计
4.测试
1.测试0是否能运行
2.测试正整数8
5.调试
6.源代码
在这里插入代package TuringMachine;
import java.util.Random;
import java.util.Scanner;
public class TuringMachine {
//将整型十进制正数编码转化为所需要的二进制原码
static StringBuffer toBinary(int x){
String s;
s = Integer.toBinaryString(x); //返回int变量的二进制表示的字符串。
//转化成扩展二进制编码
StringBuffer sb = new StringBuffer(s.replace("1","10"));
sb.append("11000"); //往转化的扩展二进制编码后添加“,”和补0的扩展二进制编码
return sb;
}
//将得到的编码进行乘2计算
static void calculate(StringBuffer sb){
int inState = 0; //内态变量
//通过扩展二进制编码字符长度进行循环计算
for(int i=0; i<sb.length(); i++){
/*charAt()方法返回指定索引i处字符
set charAt()设置当前索引处字符内容*/
//内态为0,输入为0 -> 内态为0,输出为0,右移计算下一位
if(inState==0 & sb.charAt(i)=='0'){
inState = 0;
sb.setCharAt(i,'0');
System.out.println("内态为0,输入为0,图灵机操作后改变为: " + sb + " 内态为:" + inState + " 输出为:" + sb.charAt(i));
continue;
}
//内态为0,输入为1 -> 内态为1,输出为0,右移计算下一位
if(inState==0 & sb.charAt(i)=='1'){
inState = 1;
sb.setCharAt(i,'0');
System.out.println("内态为0,输入为1,图灵机操作后改变为: "+sb+" 内态为:"+inState+" 输出为:"+sb.charAt(i));
continue;
}
//内态为1,输入为0 -> 内态为0,输出为1,右移计算下一位
if(inState==1 & sb.charAt(i)=='0'){
inState = 0;
sb.setCharAt(i,'1');
System.out.println("内态为1,输入为0,图灵机操作后改变为: "+sb+" 内态为:"+inState+" 输出为:"+sb.charAt(i));
continue;
}
//内态为1,输入为1 -> 内态为10,输出为0,右移计算下一位
if(inState==1 & sb.charAt(i)=='1'){
inState = 10;
sb.setCharAt(i,'0');
System.out.println("内态为1,输入为1,图灵机操作后改变为: "+sb+" 内态为:"+inState+" 输出为:"+sb.charAt(i));
continue;
}
//内态为10,输入为0 -> 内态为11,输出为1 ,右移计算下一位
if(inState==10 & sb.charAt(i)=='0'){
inState = 11;
sb.setCharAt(i,'1');
System.out.println("内态为10,输入为0,图灵机操作后改变为:"+sb+" 内态为:"+inState+" 输出为:"+sb.charAt(i));
continue;
}
//内态为11,输入为0 -> 内态为0,输出为1 ,停止计算
if(inState==11 & sb.charAt(i)=='0'){
inState = 0;
sb.setCharAt(i,'1');
System.out.println("内态为11,输入为0,图灵机操作后改变为:"+sb+" 内态为:"+inState+" 输出为:"+sb.charAt(i));
break;
}
}
}
static void test(){
Random r = new Random();
//随机生成5个数用来测试
for(int i=0;i<3;i++){
//随机生成范围[0,999)
int t=r.nextInt(999);
System.out.println("输入的数为: " + t);
StringBuffer sb = toBinary(t);
System.out.println("编码后为:" + sb);
calculate(sb);
System.out.println("计算结果为:" + sb);
//将末尾的逗号去掉
sb.delete(sb.length()-2, sb.length());
//把扩展二进制编码的10替换成为1,对扩展二进制编码进行收缩
String s = sb.toString().replace("10", "1");
System.out.println("计算结果转换为二进制为:" + s);
//Integer.parseInt(String s ,int radix)方法,以十进制输出radix进制数s
System.out.println("计算结果转换为十进制为:"+Integer.parseInt(s, 2));
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
sc.close();
StringBuffer sb = toBinary(num);
System.out.println("编码后为:" + sb);
calculate(sb);
System.out.println("计算结果为:" + sb);
//将末尾的逗号去掉
sb.delete(sb.length()-3, sb.length());
//把扩展二进制编码的10替换成为1
String s = sb.toString().replace("10", "1");
System.out.println("计算结果转换为二进制为:" + s);
//Integer.parseInt(String s ,int radix)方法,以十进制输出radix进制数s
System.out.println("计算结果转换为十进制为:"+Integer.parseInt(s, 2));
// //测试
// test();
}
}
7.总结
本次的作业是模拟图灵机XN2,主要的难点在于怎么把输入的十进制数转化为扩展二进制编码,以及应用图灵机XN2的指令,将内态与输入改变,最后进行输出。在将十进制数转化为二进制数时,使用了toBinaryString()方法将之转化为二进制,使用了parseInt()方法将二进制转化为十进制,在进行指令的时候,用了for循环来执行。在进行这次的模拟图灵机实验中,也更加弄清了图灵机的性能以及对图灵机XN*2的步骤有了更清的了解。