C++ 入門指南 V2.00 - 單元 21 範例及練習程式碼



encrypt.h


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
26
27
28
29
30
// 從標準程式庫中引入 string
#include <string>
// 使用 std 中的 string 名稱
using std::string;
 
// 定義兩個巨集常數
#define DIFF 97
#define N 26
 
// 宣告 Encrypt 類別
class Encrypt {
public:
   // 宣告建構函數
   Encrypt();
   // 宣告 setter 與 getter 成員函數
   void set_code_array();
   void set_code_array(string);
   string get_code_array();
   // 宣告編碼、解碼的成員函數
   string ToEncode(string);
   string ToDecode(string);
  
private:
   // 密碼表字串
   string code_array;
};
 
/* encrypt.h
   Kaiching Chang
   2014-4 */

encrypt.cpp


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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// 引入標準程式庫中的 cstdlib 及 ctime
#include <cstdlib> // srand(), rand()
#include <ctime>   // time()
 
// 引入 Encrypt 類別的標頭檔
#include "encrypt.h"
 
// Encrypt 的建構函數
Encrypt::Encrypt() {
   // 呼叫 setter 設定 code_array
   set_code_array();   
}
 
// 設定 code_array 的 setter 成員函數
void Encrypt::set_code_array() {
   // 設定擬隨機數的種子
   srand(time(0));
 
   // 取得 a 、 b 值
   int a = 0;
   int b = 0;
   while (a % 2 == 0) {
      a = rand() % 10;
      b = rand() % 10;
   }
 
   // 利用公式建立密碼表字串
   int x, y, m;
   char r;
   char c = 'a';
   string s;
   int i;
   for (i = 0; i < N; i++) {
      x = c;
      y = x * a + b;
      m = y % N;
      s += (char) m + DIFF;
      c++;
   }
 
   // 將建立好的密碼表直接設定給成員變數
   code_array = s;
}
 
// 由參數字串設定密碼表
void Encrypt::set_code_array(string s) {
   code_array = s;
}
 
// 回傳密碼表字串的 getter 成員函數
string Encrypt::get_code_array() {
   return code_array;
}
 
// 進行編碼工作的成員函數
string Encrypt::ToEncode(string s) {
   // 由參數字串取得字元的暫存變數
   char c;
   // 暫存編碼結果的字串
   string r;
   int i, m;
   // 利用迴圈走完參數字串的所有字元
   for (i = 0; i < s.size(); i++) {
      // 判斷該字元是否為英文小寫字母
      // 若是英文小寫字母就進行編碼轉換
      if (s.at(i) >= DIFF && s.at(i) < DIFF + N) {
         c = s.at(i);
         m = c - 97;
         r += get_code_array().at(m);
      }
      else {
         r += s.at(i);
      }
   }
 
   // 結束回傳編碼過的字串
   return r;
}
 
// 進行解碼工作的成員函數
string Encrypt::ToDecode(string s) {
   // 暫存解碼結果的字串
   string r;
   int i, j;
   // 第一層迴圈逐一取得每一個字元
   for (i = 0; i < s.size(); i++) {
      // 判斷該字元是否為英文小寫字母
      // 若是英文小寫字母就進行解碼轉換
      if (s.at(i) >= DIFF && s.at(i) < DIFF + N) {
         // 第二層迴圈尋找該字元在密碼表中的索引值
         // 該索引值加上 DIFF 就可轉換回原本的字元
         for (j = 0; j < N; j++) {
            if (s.at(i) == get_code_array().at(j)) {
               r += (char) j + DIFF;
               break;
            }
         }
      }
      else {
         r += s.at(i);
      }
   }
 
   // 結束回傳解碼過的字串
   return r;
}
 
/* encrypt.cpp
   Kaiching Chang
   2014-5 */

exercise2101.h


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
26
27
28
29
30
31
// 宣告 GuessGame 類別
class GuessGame {
public:
   // 宣告建構函數
   GuessGame(int);
   // 存取函數與修改函數
   int get_answer();
   int get_times();
   void set_game();
   // 工具函數
   bool FindNumber(int[], int, int);
   void ArrayNumber(int[], int);
   void ABCounter(int[], int[], int[]);
   // 命令列遊戲版本
   void Run();
  
private:
   // 資料成員區
   int answer;
   int answer_array[6];
   int length;
   int guess;
   int guess_array[6];
   int ab_array[2];
   int times;
 
};
 
/* 檔名: exercise2101.h
   作者: Kaiching Chang
   時間: 2014-5 */

exercise2101.cpp


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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <ctime> 
 
#include "exercise2101.h"
 
using namespace std;
 
GuessGame::GuessGame(int digit) {
   if (digit < 3 || digit > 6) {
      length = 4;
   }
   else {
      length = digit;
   }
    
   set_game();
}
 
int GuessGame::get_answer() {
   return answer;
}
 
int GuessGame::get_times() {
   return times;
}
 
void GuessGame::set_game() {
   srand(time(0));
 
   int m;
   int i = 0;
   int base = pow(10, length - 1);
   int result = 0;
     
   // 建立不重複的四位數
   while (i < length) {
      m = rand() % 10;
       
      // 若第一位數為 0 則重來
      if (i == 0 && m == 0) {
         continue;
      }
         
      // 將答案儲存在陣列
      answer_array[i] = m;
 
      // 有重複,這一輪重來
      if (FindNumber(answer_array, i, m)) {
         continue;
      }
      // 沒重複,將該數字加進四位數之中
      else {
         result += m * base;
         base /= 10;
         i++;
      }
   }
     
   answer = result;
   times = 0;
}
 
bool GuessGame::FindNumber(int array[], int index, int number) {
   for (int i = 0; i < length; i++) {
      if (i == index) {
         continue;
      }
         
      if (array[i] == number) {
         return true;
      }
   }
     
   return false;
}
 
void GuessGame::ArrayNumber(int array[], int number) {
   int i;
   int j = pow(10, length - 1);
   int temp = number;
   for (i = 0; i < length; i++) {
      array[i] = temp / j;
      temp %= j;
      j /= 10;
   }
}
 
void GuessGame::ABCounter(int array1[], int array2[], int array3[]) {
   int a = 0;
   int b = 0;
   for (int i = 0; i < length; i++) {
      for (int j = 0; j < length; j++) {
         if (array1[i] == array2[j]) {
            if (i == j) {
               a++;
            }
            else {
               b++;
            }
         }
      }
   }
    
   array3[0] = a;
   array3[1] = b;
}
 
void GuessGame::Run() {
   while (true) {
      // 計算次數
      times++;
       
      // 接受猜測
      cin >> guess;
      ArrayNumber(guess_array, guess);
       
      // 檢查使用者是否輸入四個不同數字
      bool state = false;
      for (int i = 0; i < 4; i++) {
         if (FindNumber(guess_array, i, guess_array[i])) {
            state = true;
         }
      }
       
      if (state) {
         cout << "Please guess 4 different numbers!!" << endl;
         continue;
      }
       
      // 檢查使用者是否輸入過少或過多的數字
      if (guess <= 999 || guess >= 10000) {
         cout << "Please input 4 numbers!!" << endl;
         continue;
      }
       
       
      // 計算 A 、 B 值
      ABCounter(answer_array, guess_array, ab_array);
 
      // 判斷使用者是否猜對
      if (answer == guess) {
         cout << "Right!! You guess " << times << " times!!" << endl;
         break;
      }
      else {
         cout << "Wrong!! " << ab_array[0] << "A" << ab_array[1] << "B!!" << endl;
      }
   }
}
 
/* 檔名: exercise2101.cpp
   作者: Kaiching Chang
   時間: 2014-5 */

exercise2102.cpp


1
2
3
4
5
6
7
8
9
10
#include "exercise2101.h"
 
int main(void) {
   GuessGame g(4);
   g.Run();
}
 
/* 檔名: exercise2102.cpp
   作者: Kaiching Chang
   時間: 2014-5 */

the end

沒有留言: