所謂的解碼也就是將編碼 (encoding) 過的小寫英文字母回覆成原來的英文小寫字母,由上圖可以看出,我們儲存表格所用的字元陣列 (array) ,恰巧依索引值 (index) 可推回原來的英文小寫字母,這是說,索引值 0 為 'q' ,所以是將原本的 'a' 變成 'q' ,因此,解碼就是依索引值重新加上 97 即可。
實際上我們需要用到巢狀迴圈 (nested loop) ,也就是在迴圈 (loop) 中有其他的迴圈,對單一英文句子而言,我們需要一個迴圈判斷每個字元是否為英文小寫字母,若是英文小寫字母,我們就需要另一個迴圈找出對應的索引值。由這樣的概念設計的解碼方法 (method) toDecode() ,如下
public string toDecode(string s) { System.Text.StringBuilder r = new System.Text.StringBuilder(); // 進行解碼的工作 int i, j; for (i = 0; i < s.Length; i++) { if (s[i] >= 97 && s[i] <= 122) { // 找出表格中對應的索引值 for (j = 0; j < 26; j++) { if (s[i] == this.Code[j]) { r.Append((char) (j + 97)); break; } } } else { r.Append(s[i]); } } return r.ToString(); }
巢狀迴圈是迴圈中包含另一個迴圈,由於我們利用縮排的方式編輯程式碼,看起來內層迴圈像是凹陷進去的巢,故稱之為巢狀迴圈。
toDecode() 與 toEncode() 相似,同樣需要一個字串 (string) 當參數 (parameter) ,結果也回傳一個字串。
解碼轉換由巢狀迴圈的部份來進行
for (i = 0; i < s.Length; i++) { if (s[i] >= 97 && s[i] <= 122) { // 找出表格中對應的索引值 for (j = 0; j < 26; j++) { if (s[i] == this.Code[j]) { r.Append((char) (j + 97)); break; } } } else { r.Append(s[i]); } }
外層迴圈會依序取得英文句子的每個字元,然後判斷是否為英文小寫字母,如果該字元是英文小寫字母,就會啟動另一個迴圈找出表格中對應的索引值出來,相反地,如果該字元不是英文小寫字母,控制變數 i 就會自動遞增,然後判斷下一個字元。
注意,這個巢狀迴圈用了兩個 for 、兩個 if ,依順序 for 、 if 、 for 、 if ,這是我們打算讓程式執行的順序,若是沒有依照這樣的順序,程式可能會跑出無法預期的結果。
完整的 Encrypt 修改如下
class Encrypt { private string cArray; public string Code { get { return cArray; } set { if (value is string && value.Length == 26) { cArray = value; } else { System.Console.WriteLine("something worng!!");; } } } public Encrypt() { System.Random r = new System.Random(); int a = 0; int b = 0; // 限定 a 為偶數 while (a % 2 == 0) { a = r.Next(1, 10); b = r.Next(1, 10); } System.Console.Write("a: " + a + ", b: " + b + ", "); int x, y, m; char c = 'a'; int i; System.Text.StringBuilder s = new System.Text.StringBuilder(); for (i = 0; i < 26; i++) { x = c; y = x * a + b; m = y % 26; s.Append((char) (m + 97)); c++; } this.cArray = s.ToString(); } public string toEncode(string s) { System.Text.StringBuilder r = new System.Text.StringBuilder(); // 進行編碼轉換 char c; int i, m; for (i = 0; i < s.Length; i++) { if (s[i] >= 97 && s[i] <= 122) { c = s[i]; m = c - 97; r.Append(this.Code[m]); } else { r.Append(s[i]); } } // 回傳字串 return r.ToString(); } public string toDecode(string s) { System.Text.StringBuilder r = new System.Text.StringBuilder(); // 進行解碼的工作 int i, j; for (i = 0; i < s.Length; i++) { if (s[i] >= 97 && s[i] <= 122) { // 找出表格中對應的索引值 for (j = 0; j < 26; j++) { if (s[i] == this.Code[j]) { r.Append((char) (j + 97)); break; } } } else { r.Append(s[i]); } } return r.ToString(); } static void Main() { string s = "There is no spoon."; for (int i = 0; i < 16; i++) { Encrypt e = new Encrypt(); System.Console.WriteLine(i + ": "+ e.toEncode(s)); System.Threading.Thread.Sleep(1000); } } } /* 《程式語言教學誌》的範例程式 http://pydoing.blogspot.com/ 檔名:encrypt.cs 功能:示範 C# 程式 作者:張凱慶 時間:西元 2012 年 10 月 */
我們用相同的句子 "There is no spoon." 編碼、解碼了八次,編譯執行結果如下
嗯,編碼與解碼都正確無誤,接下來,我們先不談如何發展圖形介面,先討論一下 C# 組織程式原始碼檔案的方式,這需要先討論一下程式結構。
中英文術語對照 | |
---|---|
解碼 | decoding |
編碼 | encoding |
陣列 | array |
索引值 | index |
巢狀迴圈 | nested loop |
迴圈 | loop |
方法 | method |
字串 | string |
參數 | parameter |
您可以繼續參考
軟體開發
相關目錄
回 C# 入門指南
回 C# 教材
回首頁
參考資料
http://msdn.microsoft.com/zh-tw/library/ms173109%28v=vs.80%29.aspx
http://msdn.microsoft.com/zh-tw/library/x9afc042.aspx
http://msdn.microsoft.com/zh-tw/library/ms229036%28v=vs.80%29.aspx
http://msdn.microsoft.com/zh-tw/library/0b0thckt.aspx
2 則留言:
在Main裡面好像少了toDecode的呼叫
這樣應該沒辦法得到如圖的執行結果吧??
System.Console.WriteLine(i + " toDecode: " + e.toDecode(e.toEncode(s)));
Main多加一行
張貼留言