C# 入門指南
單元 15 - 實作 SetCode()
SetCode() 的工作就是建立密碼表,我們需要的密碼表就是一個攪亂順序的英文字母表
⇓
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
q | z | i | r | a | j | s | b | k | t | c | l | u | d | m | v | e | n | w | f | o | x | g | p | y | h |
先來溫習一下用來編碼的數學公式
y = a * x + b
m = y % n
r = m + diff
a 與 b 預定是 0 到 9 之間的隨機整數,要取得隨機整數的話, .NET 有程式可用,倒是現在先不用急著一次到位,我們先把 a 設定成 3 , b 設定成 5 測試看看好了,如此 SetCode() 的實作如下
// 建立密碼表
public void SetCode()
{
// 宣告變數
int a, b, x, y, m;
char c = 'a';
// a 、 b 初始化
a = 3;
b = 5;
code = "";
// 建立密碼表的迴圈
for (int i = 0; i < 26; i++)
{
x = c;
y = x * a + b;
m = y % 26;
code += Convert.ToChar(m + 97);
c++;
}
}
code 欄位的初值設定為空字串 (empty string)
code = "";
另外設定兩個控制變數 (control variable) ,字元型態的 c 為記錄目前處理的字母
char c = 'a';
for 迴圈中的 i 則是記錄迴圈 (loop) 進行的次數
for (int i = 0; i < 26; i++)
因為英文字母表的小寫字母共有 26 個,因此公式用迴圈跑了 26 次
// 建立密碼表的迴圈
for (int i = 0; i < 26; i++)
{
x = c;
y = x * a + b;
m = y % 26;
code += Convert.ToChar(m + 97);
c++;
}
控制變數 c 最初的值為起始字元,也就是英文字母表的第一個字母 'a' ,這裡並沒有直接拿變數 c 進行計算,而是把變數 c 的值指派給整數型態的 x
x = c;
會這樣做的原因很簡單,因為需要一個變數表示目前處理的字元,而字元型態的變數可以如同整數型態進行加減乘除,因此迴圈的最後利用遞增將變數 c 轉移到下一個字元,例如迴圈從 'a' 開始,第二個處理的字元為 'b' ,第三個為 'c' ,以此類推
c++;
由於 C# 的字元型態其實就是範圍較小的整數,因此也可以直接將迴圈的控制變數 i 設定為 97 ,讓 i 依次遞增到 97 + 26 為止。
迴圈中逐次利用 System 中 Convert 的 ToChar() 方法,將整數直接轉換成字元,再用 += 將字元附加到 code 欄位之後
code += Convert.ToChar(m + 97);
建構子就是呼叫 SetCode() 設定 code 欄位,目前的實作版本如下
using System;
namespace EncryptDemo02
{
class EncryptDemo02
{
// 宣告密碼表欄位
public string code;
// 建構子,呼叫建立密碼表的 SetCode() 方法
public EncryptDemo02()
{
SetCode();
}
// 建立密碼表
public void SetCode()
{
// 宣告變數
int a, b, x, y, m;
char c = 'a';
// a 、 b 初始化
a = 3;
b = 5;
code = "";
// 建立密碼表的迴圈
for (int i = 0; i < 26; i++)
{
x = c;
y = x * a + b;
m = y % 26;
code += Convert.ToChar(m + 97);
c++;
}
}
// 編碼方法
public string ToEncode(string s)
{
return s;
}
// 解碼方法
public string ToDecode(string s)
{
return s;
}
}
class Program
{
static void Main(string[] args)
{
// 建立密碼物件
EncryptDemo02 e = new EncryptDemo02();
// 印出密碼表
Console.WriteLine(e.code);
}
}
}
//《程式語言教學誌》的範例程式
// http://kaiching.org/
// 專案:EncryptDemo02
// 檔名:Program.cs
// 功能:示範利用 C# 設計 Encrypt 類別
// 作者:張凱慶
測試部分就是印出密碼表,執行結果如下
C:\EncryptDemo02> dotnet run |
knqtwzcfiloruxadgjmpsvybeh |
C:\EncryptDemo02> |
結果如預期,一個英文小寫字母恰恰好對應到另外一個英文小寫字母,這樣我們的公式就 ok 了嗎? a 等於 3 跟 b 等於 5 是沒問題的,可是我們希望 a 與 b 可以是 0 到 9 之間的任意整數,這樣就有 100 種組合說,所以我們接下來要繼續測試,看看是不是每一種組合都 ok 囉!
相關教學影片
中英文術語對照 | |
---|---|
控制變數 | control variable |
空字串 | empty string |
迴圈 | loop |
參考資料 | |
---|---|
1. C# 程式設計手冊 | Microsoft Docs - 類別 |
重點整理 |
---|
1. 實作 SetCode() 是先將公式中的 a 設成 3 , b 設成 5 ,然後用迴圈利用兩個控制變數 i 與 c 逐一計算每個字元。 |
2. 字元型態就是範圍較小的整數,因此可直接進行算術運算。 |
3. 計算完利用 System 中 Convert 的 ToChar() 方法,將整數直接轉換成字元,再用 += 將字元附加到 code 欄位之後。 |
問題與討論 |
---|
1. 為什麼不把建立對換表格直接寫在建構子裡就好了? |
2. 為什麼數字要用 Convert 的 ToChar() 方法轉轉換成字元,才可以用 += 附加到字串物件的最後? |
練習 |
---|
1. 承接上一個單元的猜數字遊戲,另建立一個專案 Exercise1501 ,在 Program 類別的 Main() 方法接受使用者輸入,加入判斷使用者是否猜對的邏輯及提示訊息。 |
2. 承上題,另建立一個專案 Exercise1502 ,將 answer 改為字串。 |