Week 3 作業檢討

盧冠綸 @ Sprout 2022

維吉尼亞的統計學

維吉尼亞的統計學

可參考的思路:  

用 int 陣列來存要輸出的 26 個數字。  

維吉尼亞的統計學

我要怎麼處理那個二維表格:  

ㄧ、用 if else。

                慢,有 26 * 26 = 676 種組合

二、用 ASCII code 的運算。

                快,也許很快就能寫好。

維吉尼亞的統計學

用 ASCII code 的運算要怎麼做?

=> 先來找規律:

      'a' 和 'a' 得到 'a'

      'a' 和 'b' 得到 'b'

      'a' 和 'z' 得到 'z'

 

      'b' 和 'a' 得到 'b'

      'b' 和 'b' 得到 'c'

      'b' 和 'z' 得到 'a'

感覺很像加法?

'a' 是 0,'b' 是 1,...

維吉尼亞的統計學

我要怎麼讓 'a' 是 0,'b' 是 1,...?

=> 把它減 'a'!

這樣子,我們就知道,

兩個字母,letter1 和 letter2,會合成什麼新字母了。

=>  (letter1 - 'a') + (letter2 - 'a')              (X

=> ((letter1 - 'a') + (letter2 - 'a')) % 26   (O

%26 是為了避免超出範圍

#include <iostream>
#include <cstring>

int main(){
    // a和b是輸入的兩個字串
    char a[1005], b[1005];
    std::cin >> a >> b;
    unsigned long len = strlen(a);
    // answer是要輸出的陣列,記得初始化!!
    int answer[26] = {0};
    for (unsigned long i=0 ; i<len ; i++){
        int temp = (a[i] - 'a') + (b[i] - 'a');
        answer[temp%26] += 1;
    }
    // 處理輸出 (最後不用空白&換行)
    for (int i=0 ; i<25 ; i++){
        std::cout << answer[i] << " ";
    }
    std::cout << answer[25];
}

答案:  

維吉尼亞的統計學

Sproutle

Sproutle

我要怎麼知道玩家會猜幾次?

=> 用 while 迴圈,直到玩家猜的和答案一樣。 

    => do{

               // do something

          while (strcmp(answer, guess) != 0);

我要怎麼存資料?

=> 用字元陣列存我想輸出的東西。

Sproutle

架構:

#include <iostream>
#include <cstring>

int main(){
    宣告 & cin 答案
    用strlen算答案字串長度
    do{
        宣告字元陣列存猜的字
        宣告字元陣列存要輸出的東西
        for (int i=0 ; i<答案長度 ; i++){
            算出第i個字元的顏色,對應到'A'、'B'、'C'
        }
        std::cout << 要輸出的字元陣列 << std::endl;
    }while (strcmp(答案,猜的字) != 0);
}

Sproutle

詳細程式(可下拉):

#include <iostream>
#include <cstring>

int main(){
    // answer用來存答案
    char answer[15];
    std::cin >> answer;
    int len = strlen(answer);
    // end代表小明是否猜到答案
    bool end = false;
    do{
        // guess是小明猜的字,
        // output是我想輸出的東西,內含'A'、'B'、'C'
        char guess[15], output[15] = {'\0'};
        std::cin >> guess;
        for (int i=0 ; i<len ; i++){
            // 處理output[i],應是'A'或'B'或'C'
            for (int j=0 ; j<len ; j++){
                if (guess[i] == answer[j]){
                    if (i == j){
                        output[i] = 'A';
                    }else{
                        output[i] = 'B';
                    }
                }
            }
            if ((output[i] != 'A') and (output[i] != 'B')){
                output[i] = 'C';
            }
        }
        // 輸出output。注意output[len]必須是'\0'。
        std::cout << output << std::endl;
        // 如果小明猜中答案,就離開迴圈
        if (strcmp(guess, answer) == 0){
            end = true;
        }
    }while (end == false);
}

Sproutle

小建議:

如果你寫到後面看不懂自己寫的程式...

    => 取個有識別性的的變數名稱,

         answer、guess              (O

         a、b、x、y、xx             (X

    => 試著簡化你的程式。

         如,刪掉不必要的變數

         如,盡量不要出現太多層的巢狀迴圈

Sproutle

小建議:

WA怎麼修?

    => 檢查看看你的字串結尾是不是確定有'\0'?

TLE怎麼修?

    => 自己生些簡單測資測看看你的程式。

=> 看看自己的迴圈有沒有寫錯。

謝謝大家

20220326 上週作業檢討

By allen522019

20220326 上週作業檢討

  • 291