题目分析
对于扩展二进位的乘2运算比进一位图灵机更为简单。通过如下指令给出图灵机(XN*2) 在扩展的二进位上实现这个运算的指令,实现*2操作
0 0 → 0 0R
0 1 → 1 0R
1 0 → 0 1R
1 1 → 10 0R
10 0 → 11 1R
11 0 → 0 1 STOP
算法构造
用户输入数字,将数字转换为二进制码,将二进制转换为二进制扩展码,通过图灵机(XN*2)实现乘2操作得到结果的二进制扩展码,再将二进制扩展码转换为对应的二进制码,由二进制得十进制结果
1.toBinaryString()将整数转换为二进制码
2.toBinaryExtend()将二进制码转换为二进制扩展码
3.processXNMulitTwo()图灵机(XN*2)实现乘2操作整个过程
4.extendToBinary()将二进制扩展码转换为二进制
5.binaryToInt()二进制转换为十进制
6.printArray()将图灵机的步骤打印
STOP
算法实现
package EmbarkationTwo;
import java.util.Scanner;
public class Turing {
/**
* 实现将一个字符串转换成对应的二进制扩展码
* @param str
* @return 返回str的二进制扩展码
*/
private static String toBinaryExtend(String str) {
char[] arr = str.toCharArray();
if (arr[0] == '0') {
return "0";
}
StringBuilder cur = new StringBuilder();
cur = cur.append("010");
for (int i = 1; i < arr.length; i++) {
if (arr[i] == '1') {
cur = cur.append("10");
} else {
cur = cur.append("0");
}
}
return cur.append("110").toString();
}
/**
* 打印数组当前状态的值
* @param arr 待打印数组
* @param i 操作到数组中第 i 个字符
* @param state 此时图灵机的状态
*/
private static void printArray(char[] arr, int i, int state) {
System.out.printf("第%2d步:",i + 1);
System.out.printf("内部状态:%-2d 当前值:%c 扩展码:",state,arr[i]);
for (char ch: arr
) {
System.out.print(ch);
}
System.out.println();
}
/**
* 图灵机实现乘的过程
* @param str 二进扩展码
* @return 对应二进制扩展码的完成乘2之后得到的扩展码
*/
private static String processXNMultiTwo(String str) {
int state = 0;
char[] arr = str.toCharArray();
for (int i = 0; i < arr.length; i++) {
if (state == 0 && arr[i] == '0') {
printArray(arr,i,state);
arr[i] = '0';
state = 0;
} else if (state == 0 && arr[i] == '1') {
printArray(arr,i,state);
arr[i] = '0';
state = 1;
} else if (state == 1 && arr[i] == '0') {
printArray(arr,i,state);
arr[i] = '1';
state = 0;
} else if (state == 1 && arr[i] == '1') {
printArray(arr,i,state);
arr[i] = '0';
state = 10;
} else if (state == 10 && arr[i] == '0') {
printArray(arr,i,state);
arr[i] = '1';
}
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
sb.append(arr[i]);
}
sb.append("1");
printArray(sb.toString().toCharArray(),arr.length,11);
sb.append("0");
printArray(sb.toString().toCharArray(),arr.length + 1,0);
System.out.println("STOP");
return sb.toString();
}
/**
* 求一个字符串对应的二进制
* @param str 待求二进制的字符串
* @return str的二进制表示
*/
private static String extendToBinary(String str) {
char[] arr = str.toCharArray();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
if (arr[i] == '1' && arr[i + 1] == '0') {
sb.append('1');
} else if ((i + 1) < arr.length && arr[i] == '0' && arr[i + 1] == '0') {
sb.append('0');
} else if (arr[i] == '1' && arr[i + 1] == '1') {
sb.append(',');
i++;
}
}
return sb.toString();
}
/**
* 求一个字符串(二进制)的整数形式
* @param str 待求整数的二进制字符串
* @return str的对应的十进制整数
*/
private static int binaryToInt(String str) {
int n = str.length() - 1;
String indexStr = str.substring(0,str.length() - 1);
char[] arr = indexStr.toCharArray();
int sum = 0;
boolean judge = false;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == '1') {
judge = true;
}
if (judge) {
sum += (arr[i] - 48) * Math.pow(2,n - i - 1);
}
}
return sum;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("通过图灵机(XN * 2) 的方式在扩展的二进位上实现 * 2操作");
System.out.print("输入一个整数:");
int before = input.nextInt();
String beforeStr = Integer.toBinaryString(before);
String beforeBinaryExtend = toBinaryExtend(beforeStr);
String afterBinaryExtend = processXNMultiTwo(beforeBinaryExtend);
System.out.println("最终的扩展码:" + afterBinaryExtend);
String afterBinary = extendToBinary(afterBinaryExtend);
System.out.println("最终的二进制码:" + afterBinary);
int afterResult = binaryToInt(afterBinary);
System.out.println("最终值:" + afterResult);
}
}
经验归纳
通过对图灵机的模拟我深刻的了解了当时计算机进行运算的整体过程,感受到人也可以和机器交流,深深的感受到代码的魅力,没有当时的图灵机思想计算机不可能实现运算操作。
图灵机证明了通用计算理论,肯定了计算机实现的可能性,同时它给出了计算机应有的主要架构;图灵机模型引入了读写与算法与程序语言的概念,极大的突破了过去的计算机器的设计理念;图灵机模型理论是计算学科最核心的理论,因为计算机的极限计算能力就是通用图灵机的计算能力,很多问题可以转化到图灵机这个简单的模型来考虑。
因为我使用Java写的结合方法的封装性实现了toBinaryString()将整数转换为二进制码,toBinaryExtend()将二进制码转换为二进制扩展码,processXNMulitTwo()图灵机(XN*2)实现乘2操作整个过程,extendToBinary()将二进制扩展码转换为二进制,binaryToInt()二进制转换为十进制,printArray()将图灵机的步骤打印使代码的可读性和实用性大大增加。我体会到了结构化封装的重要性和必要性。