所謂的解碼也就是將編碼 (encoding) 過的小寫英文字母回覆成原來的英文小寫字母,由上圖可以看出,我們儲存表格所用的陣列 (array) ,恰巧依索引值 (index) 可推回原來的英文小寫字母,這是說,索引值 0 為 'q' ,所以是將原本的 'a' 變成 'q' ,因此,解碼就是依索引值重新加上 diff 即可。
實際上我們需要用到巢狀迴圈 (nested loop) ,也就是在迴圈 (loop) 中有其他的迴圈,對單一英文句子而言,我們需要一個迴圈判斷每個字元是否為英文小寫字母,若是英文小寫字母,我們就需要另一個迴圈找出對應的索引值。由這樣的概念設計的解碼方法 (method) toDecode() ,如下
public String toDecode(String s) { char[] cs = s.toCharArray(); int i, j; char r; String rs = ""; Character cc; // 進行解碼的工作 for (i = 0; i < cs.length; i++) { // 判斷是否為英文小寫字母 if (cs[i] >= 97 && cs[i] <= 122) { // 找出表格中對應的索引值 for (j = 0; j <= getArray().length; j++) { if (cs[i] == getArray()[j]) { cs[i] = (char) (j + getDif()); break; } } } } // 將字元陣列儲存為字串 for (i = 0; i < cs.length; i++) { cc = new Character(cs[i]); rs = rs.concat(cc.toString()); } return rs; }
巢狀迴圈是迴圈中包含另一個迴圈,由於我們利用縮排的方式編輯程式碼,看起來內層迴圈像是凹陷進去的巢,故稱之為巢狀迴圈。
toDecode() 與 toEncode() 相似,同樣需要一個字串 (string) 當參數 (parameter) ,結果也回傳一個字串,並且一樣將字串先以 toCharArray() 方法轉換成字元陣列 (array) ,然後才開始進行解碼轉換工作。
解碼轉換由巢狀迴圈的部份來進行
// 進行解碼的工作 for (i = 0; i < cs.length; i++) { // 判斷是否為英文小寫字母 if (cs[i] >= 97 && cs[i] <= 122) { // 找出表格中對應的索引值 for (j = 0; j <= getArray().length; j++) { if (cs[i] == getArray()[j]) { cs[i] = (char) (j + getDif()); break; } } } }
外層迴圈會依序取得英文句子的每個字元,然後判斷是否為英文小寫字母,如果該字元是英文小寫字母,就會啟動另一個迴圈找出表格中對應的索引值出來,相反地,如果該字元不是英文小寫字母,控制變數 i 就會自動遞增,然後判斷下一個字元。
注意,這個巢狀迴圈用了兩個 for 、兩個 if ,依順序 for 、 if 、 for 、 if ,這是我們打算讓程式執行的順序,若是沒有依照這樣的順序,程式可能會跑出無法預期的結果。
我們只增加一個 toDecode() 方法,完整的 Encrypt 類別可以參考 Encrypt.java 。
EncryptDemo 需要修改,然後才可對 toDecode() 進行測試
// 測試 Encrypt 的類別 public class EncryptDemo { public static void main(String[] args) { System.out.println(); String s[] = {"There is no spoon.", "It is all around us.", "Free your mind.", "Follow the white rabbit.", "Choice. The problem is choice.", "Action, reaction. Cause, effect.", "Everything that has a beginning has an end.", "Because I choose to."}; Encrypt e = new Encrypt(); String t = ""; for (int i = 0; i < 8; i++) { t = e.toEncode(s[i]); System.out.println(t); t = e.toDecode(t); System.out.println(t); } System.out.println(); } } /* 《程式語言教學誌》的範例程式 http://pydoing.blogspot.com/ 檔名:EncryptDemo.java 功能:示範 Java 程式 作者:張凱慶 時間:西元 2011 年 4 月 */
我們在電影駭客任務 The Matrix 系列中找了八個著名對白,儲存在字串陣列 s[] 之中,然後用一個 for 迴圈將每一句對白先編碼,印出編碼的結果,再把編碼後的字串解碼,然後印出還原後的字串,如果還原後的字串與 s[] 裡頭的相符,就表示我們的解碼方法是正確的。
記得, Encrypt 與 EncryptDemo 兩個類別都修改過,因此需要先編譯才可執行
嗯,編碼與解碼都正確無誤,接下來,我們先不談如何發展圖形介面,先討論一下 Java 組織程式原始碼檔案的套件吧!
中英文術語對照 | |
---|---|
解碼 | decoding |
編碼 | encoding |
陣列 | array |
索引值 | index |
巢狀迴圈 | nested loop |
迴圈 | loop |
方法 | method |
字串 | string |
參數 | parameter |
陣列 | array |
您可以繼續參考
軟體開發
相關目錄
回 Java 入門指南
回 Java 教材目錄
回首頁
參考資料
The JavaTM Tutorials: Getting Started
The JavaTM Tutorials: Learning the Java Language
The JavaTM Tutorials: Essential Classes
The Java Language Specification, Third Edition
本文於 2013 年 1 月訂正
2 則留言:
問1:
for (j = 0; j <= getArray().length; j++) {
的 j<= 是否應該是 j< 才對?
問2:
for (int i = 0; i < 8; i++) {
其中的8,是否改為s.length較好?
謝謝指導!
關於問1 ,是的,完全正確的寫法是要寫成 < 而非 <= ,倒是這裡寫成 <= 並不會出錯。
關於問2 ,如果程式是接受未知大小的字串陣列,自然用 s.length 會比較合適,但若已經確定大小,直接用數字就已經有清楚的語意。
張貼留言