如何用Java模擬XN*2圖靈機
對于XN*2圖靈機進行模擬,任意給定的十進制數(shù),轉(zhuǎn)換為收縮擴展二進制的編碼,再編程模擬此Turing機的運行過程,要求輸出從開始運行起的每一步驟的結(jié)果。用C或C++或Java或Python語言實現(xiàn)程序解決問題。
要求:1. 程序風(fēng)格良好(使用自定義注釋模板);
2. 提供友好的輸入輸出,并進行輸入數(shù)據(jù)的正確性驗證。
算法分析:1. 將十進制數(shù)轉(zhuǎn)換為二進制數(shù);
2. 將二進制數(shù)轉(zhuǎn)換為收縮擴展二進制的編碼;
3. 根據(jù)當(dāng)前的內(nèi)態(tài)和輸入執(zhí)行XN*2圖靈機的指令;
4. 將結(jié)果的二進制編碼轉(zhuǎn)換為二進制數(shù);
5. 將二進制數(shù)轉(zhuǎn)換為十進制數(shù),實現(xiàn)乘2運算功能。
概要設(shè)計:算法流程圖如下:

輸入的十進制數(shù)
正確的二進制編碼
輸出的二進制編碼
正確的運算結(jié)果
輸出的運算結(jié)果
0
0011000
0011000
0
0
3
0101011000
0101011000
6
6
18
0100010011000
0100010011000
36
36
運行結(jié)果:


①對調(diào)用指令的方法進行調(diào)試,開始時binCodeList的size為0,導(dǎo)致執(zhí)行binCodeList.set(i, “0”)時出現(xiàn)錯誤,進過調(diào)試后發(fā)現(xiàn)是因為沒給方法設(shè)置binCodeList的參數(shù),導(dǎo)致方法中用的是類中空的binCodeList。在方法的參數(shù)中加上List<String> binCodeList就可以解決。

②對將二進制編碼轉(zhuǎn)換為十進制數(shù)的方法進行調(diào)試,開始時運算結(jié)果出現(xiàn)錯誤,調(diào)試后發(fā)現(xiàn)是判斷第i個字符為1,第i+1個字符為0后,沒有將i再加1,導(dǎo)致下次循環(huán)又遍歷到i+1的0,于是有些步驟結(jié)果就會多出0。在if (binCode.charAt(i + 1) == ’0’){…}代碼塊中加上i++就可以解決。

import java.util.*; /** * @description: 該類模擬XN*2圖靈機,對任意給定的十進制數(shù),轉(zhuǎn)換為收縮擴展二進制的編碼,并可輸出運行中每一步驟的結(jié)果 */public class TuringMachine { private int internalState; // 圖靈機的內(nèi)態(tài) private String binCode; // 二進制編碼 Function f = new Function(); // 需要用到的方法 List<String> binCodeList = new ArrayList<>(); // 用來存放二進制編碼 static int r = 0; // 當(dāng)r為1時機器向右移動一格 static int s = 0; // 當(dāng)s為1時機器停止運行 TuringMachine() {internalState = 0;binCode = '0'; } public int getInternalState() {return internalState; } public void setInternalState(int internalState) {this.internalState = internalState; } public String getBinCode() {return binCode; } public void setBinCode(String binCode) {this.binCode = binCode; } /** * @description: 模擬圖靈機的運行過程 * @param: [binCode 二進制編碼] * @return: void */ public void runProcess(String binCode) {binCodeList = f.toArrayList(binCode); // 將二進制碼binCode轉(zhuǎn)換為ArrayList類型存放在binCodeList中// for循環(huán)對binCodeList進行遍歷,根據(jù)當(dāng)前內(nèi)態(tài)的值判斷該執(zhí)行哪條指令for (int i = 0; i < binCodeList.size(); i++) { r = 1; // 當(dāng)s==1時機器停止,跳出循環(huán) if (s == 1) {break; } switch (getInternalState()) {// 內(nèi)態(tài)為0時執(zhí)行指令1case 0: instruction_1(binCodeList.get(i), i, binCodeList); break;// 內(nèi)態(tài)為1時執(zhí)行指令2case 1: instruction_2(binCodeList.get(i), i, binCodeList); break;// 內(nèi)態(tài)為10時執(zhí)行指令3case 10: instruction_3(binCodeList.get(i), i, binCodeList); break;// 內(nèi)態(tài)為11時執(zhí)行指令4case 11: instruction_4(binCodeList.get(i), i, binCodeList); break;default: break; }}System.out.println('XN*2圖靈機計算的最終結(jié)果為:');f.toDecNum(f.toString(binCodeList)); // 將binCodeList轉(zhuǎn)換為String類型的二進制編碼binCode,再轉(zhuǎn)換為int類型的十進制數(shù)decNum } /** * @description: 根據(jù)指令對每一步驟結(jié)果進行打印 * 指令1: 0 0 -> 0 0 R * 0 1 -> 1 0 R * 指令2: 1 0 -> 0 1 R * 1 1 -> 10 0 R * 指令3: 10 0 -> 11 1 R * 指令4: 11 0 -> 0 1 STOP * @param: [input 輸入, i 循環(huán)的次數(shù)從0開始, binCodeList 存放二進制編碼binCode] * @return: void */ private void instruction_1(String input, int i, List<String> binCodeList) {System.out.println('當(dāng)前的內(nèi)態(tài)為:' + getInternalState() + ',輸入為:' + input);if (input.equals('0')) { System.out.println('執(zhí)行此條指令后的內(nèi)態(tài)為:' + getInternalState() + ',輸入為:' + binCodeList.get(i) + ',右移'); System.out.println('此步驟的結(jié)果為:'); System.out.println(f.toString(binCodeList));}if (input.equals('1')) { setInternalState(1); binCodeList.set(i, '0'); System.out.println('執(zhí)行此條指令后的內(nèi)態(tài)為:' + getInternalState() + ',輸入為:' + binCodeList.get(i) + ',右移'); System.out.println('此步驟的結(jié)果為:'); System.out.println(f.toString(binCodeList));}System.out.println(); } private void instruction_2(String input, int i, List<String> binCodeList) {System.out.println('當(dāng)前的內(nèi)態(tài)為:' + getInternalState() + ',輸入為:' + input);if (input.equals('0')) { setInternalState(0); binCodeList.set(i, '1'); System.out.println('執(zhí)行此條指令后的內(nèi)態(tài)為:' + getInternalState() + ',輸入為:' + binCodeList.get(i) + ',右移'); System.out.println('此步驟的結(jié)果為:'); System.out.println(f.toString(binCodeList));}if (input.equals('1')) { setInternalState(10); binCodeList.set(i, '0'); System.out.println('執(zhí)行此條指令后的內(nèi)態(tài)為:' + getInternalState() + ',輸入為:' + binCodeList.get(i) + ',右移'); System.out.println('此步驟的結(jié)果為:'); System.out.println(f.toString(binCodeList));}System.out.println(); } private void instruction_3(String input, int i, List<String> binCodeList) {System.out.println('當(dāng)前的內(nèi)態(tài)為:' + getInternalState() + ',輸入為:' + input);if (input.equals('0')) { setInternalState(11); binCodeList.set(i, '1'); System.out.println('執(zhí)行此條指令后的內(nèi)態(tài)為:' + getInternalState() + ',輸入為:' + binCodeList.get(i) + ',右移'); System.out.println('此步驟的結(jié)果為:'); System.out.println(f.toString(binCodeList));}System.out.println(); } private void instruction_4(String input, int i, List<String> binCodeList) {System.out.println('當(dāng)前的內(nèi)態(tài)為:' + getInternalState() + ',輸入為:' + input);if (input.equals('0')) { setInternalState(0); binCodeList.set(i, '1'); System.out.println('執(zhí)行此條指令后的內(nèi)態(tài)為:' + getInternalState() + ',輸入為:' + binCodeList.get(i) + ',STOP'); System.out.println('此步驟的結(jié)果為:'); System.out.println(f.toString(binCodeList));}s = 1;System.out.println(); } public static void main(String[] args) {TuringMachine tm = new TuringMachine(); // 創(chuàng)建TuringMachine的實例tmSystem.out.println('請輸入一個十進制數(shù):');Scanner scanner = new Scanner(System.in);try { int decNum = scanner.nextInt(); tm.setBinCode(tm.f.toBinCode(decNum)); // 將十進制數(shù)轉(zhuǎn)換為二進制編碼并賦值給binCode System.out.println(); tm.runProcess(tm.getBinCode()); // 運行圖靈機} catch (InputMismatchException ex) { System.out.println('輸入有誤!');} } } /** * @description: 該類具有圖靈機TuringMachine運行過程中所需要的一些方法 */class Function { /** * @description: 將十進制數(shù)轉(zhuǎn)換為二進制編碼 * @param: [decNum 十進制數(shù)] * @return: java.lang.String */ public String toBinCode(int decNum) {String binCode = '';String binNum = Integer.toBinaryString(decNum); // 十進制數(shù)轉(zhuǎn)換為二進制數(shù)binNum += ','; // 用,標識此二進制數(shù)到此已完整,后面的0都忽略不計System.out.println('這個數(shù)的二進制表示為:' + binNum);// 利用for循環(huán)對二進制數(shù)binNum中的字符進行遍歷,根據(jù)其中的每個字符得出二進制編碼binCodefor (int i = 0; i < binNum.length(); i++) { // 0 -> 0 if (binNum.charAt(i) == ’0’) {binCode += '0';// 1 -> 10 } else if (binNum.charAt(i) == ’1’) {binCode += '10';// , -> 110 } else if (binNum.charAt(i) == ’,’) {binCode += '110'; }}binCode = '0' + binCode + '00';System.out.println('這個數(shù)的二進制編碼為:' + binCode);return binCode; } /** * @description: 將二進制編碼轉(zhuǎn)換為十進制數(shù) * @param: [binCode 二進制編碼] * @return: int */ public int toDecNum(String binCode) {int decNum = 0;String binNum = '';// 先利用for循環(huán)對ArrayList類型的binCode進行遍歷,根據(jù)其中的每個元素得出二進制編碼binCodefor (int i = 0; i < binCode.length(); i++) { // 0 -> 0 if (binCode.charAt(i) == ’0’) {binNum += '0'; } else if (binCode.charAt(i) == ’1’) {// 10 -> 1if (binCode.charAt(i + 1) == ’0’) { binNum += '1'; i++; // 110 -> ,} else if (binCode.charAt(i + 1) == ’1’) { binNum += ','; break;} }}System.out.println('二進制表示:' + binNum);decNum = Integer.parseInt(binNum.substring(0, binNum.length() - 1), 2); // 將二進制編碼binCode轉(zhuǎn)化為十進制數(shù)System.out.println('十進制表示:' + decNum);return decNum; } /** * @description: 將二進制編碼binCode存放到binCodeList中 * @param: [binCode 二進制編碼] * @return: java.util.List<java.lang.String> */ public List<String> toArrayList(String binCode) {binCode = binCode.replaceAll('', ' ').trim(); // 將binCode中的每個字符用空格分隔開,并去掉首尾的空格// 根據(jù)分隔符空格分隔出binCode中的每個字符存放到binCodeList中List<String> binCodeList = new ArrayList<>(Arrays.asList(binCode.split(' ')));return binCodeList; } /** * @description: 將binCodeList轉(zhuǎn)換為二進制編碼binCode * @param: [binCodeList 存放binCode的容器] * @return: java.lang.String */ public String toString(List<String> binCodeList) {String binCode = String.join('', binCodeList);return binCode; } }總結(jié)
本次測試是模擬圖靈機對十進制數(shù)進行乘2運算,并輸出每一步驟的結(jié)果。
本次測試的關(guān)鍵問題在于圖靈機運行過程和算法的理解,圖靈機判斷當(dāng)前內(nèi)態(tài)和輸入后執(zhí)行指令,在這里我才用switch語句根據(jù)內(nèi)態(tài)的值判斷執(zhí)行哪個指令方法,再根據(jù)輸入判斷具體執(zhí)行什么指令,通過for循環(huán)模擬右移操作。到此這篇關(guān)于如何用Java模擬XN*2圖靈機的文章就介紹到這了,更多相關(guān)Java內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!
相關(guān)文章:
1. 使用Python webdriver圖書館搶座自動預(yù)約的正確方法2. JavaScript創(chuàng)建表格的方法3. ASP.NET MVC使用jQuery ui的progressbar實現(xiàn)進度條4. PHP如何開啟Opcache功能提升程序處理效率5. Android Studio 3.5格式化布局代碼時錯位、錯亂bug的解決6. 淺談由position屬性引申的css進階討論7. Python3 json模塊之編碼解碼方法講解8. Linux刪除系統(tǒng)自帶版本Python過程詳解9. 在線php代碼縮進、代碼美化工具:PHP Formatter10. Android 簡單的實現(xiàn)滑塊拼圖驗證碼功能

網(wǎng)公網(wǎng)安備