8. What's Cryptanalysis? (CPE10402, UVA10008) - CPE一顆星解答與說明

   👉  CPE 一顆星選集列表(49題) 題目說明與解答


題目


  • 對密文做分析

輸入說明

  • 第一行為數字 N,表示接下來會輸入 N 行句子
  • 每一行會包含 0 個或多個字元,包括空白




輸出說明


  • 每一行輸出包含: 一個大寫(uppercase)的字母 + 空白 + 出現次數
  • 出現次數
    • 大寫字母與小寫字母視為相同(不區分大小寫)
    • 不用計算其他字元(像是空白.,等)出現的次數
    • 依照出現的次數,由大至小(descending)印出
    • 若次數相同,則以字母表(alphabet)的順序輸出
    • 沒有出現過的字母,不用輸出



解題技巧

  • 統計 26 個字母(a-z)出現的次數,由大至小輸出
  • 將字串統一轉大寫
  • 讀取字串中的字元
  • 判斷字元是否為字母


解題過程

取得輸入

  • 取得輸入筆數
    • Scanner scanner = new Scanner(System.in);
    • 使用scanner.nextInt()
      • 使用 scanner.nextInt() 取得數字 3 ,後面的換行↲ 會留著等待讀取
      • 要多寫一次scanner.nextLine(),才能把後面的換行↲ 處理掉
  • 取得句子
    • 根據筆數,使用 for 迴圈與 scanner.nextLine() 逐一讀取句子




將字串統一轉大寫

  • String text = "Wow!!!! Is this question easy?";
  • text = text.toUpperCase(); // WOW!!!! IS THIS QUESTION EASY?";



讀取字串中的字元

  • char letter = text.charAt(0) // 'W' 


判斷字元是否為字母

  • 統計時,須排除句子中的空白與 . 等符號
  • 判斷方法有兩種,擇一使用
    1. 使用 Character 外包類別判斷
      • char letter = 'W';
      • Character.isLetter(letter) 

    2. 使用 ASCII Code https://zh.wikipedia.org/wiki/ASCII
      • A - Z 對應 65 - 90
        • letter >= 65 && letter <= 90
        • letter >= 'A' && letter <= 'Z'
      • a - z 對應 97 – 122
        • letter >= 97 && letter <= 122
        • letter >= 'a' && letter <= 'z'




計算出現次數

  • 此題使用 陣列 Map 解題都可以,以下說明以 Map 解題,本頁最後解答處會放使用陣列的解答,這邊就不再針對陣列做說明
  • 使用 Map 的寫法
    • 因為題目只需要統計出現過的字母,可使用 Map 解題
  • Map 集合 <K, V>
    • https://docs.oracle.com/javase/8/docs/api/java/util/Map.html
    • 一個鍵值Key對應一個元素Value
    • 鍵值不能重複
  • TreeMap 是會根據鍵值 Key 排序的集合
  • 宣告方法
    • Map<類別, 類別> = new TreeMap <類別, 類別>();
      • 此處的類別不能放基本資料型別,要放參考資料類別
      • 以下兩種寫法都可以,選自己好記的
        • Map <Character, Integer> = new TreeMap < Character, Integer>();
        • TreeMap <CharacterInteger> = new TreeMap < Character, Integer>();
      • <Key, Value> = <字母字元, 出現次數>
  • 呼叫 Map 方法
    • 增加 
      • put(K key, V value)
    • 判斷
      • containsKey(Object key)
      • containsVaule(Object value)
    •  取Key
      • keySet() :具有唯一性的 key 集合
    •  取Value
      • get(Object key)
  • 判斷字母是否存在於 map 中,呼叫 containsKey(字母)
    • 例如呼叫 containsKey('W'),會得到布林值,可得知 W 字母是否存在 map 中
    • 若不存在,將字母存入 map 中,並將出現次數設為 1,呼叫 map.put(字母, 次數)
      • 例如 map.put('W', 1)
    • 若存在,取得該字母的出現次數,將次數 + 1 後,再更新至 map 中
      • 呼叫 map.get(字母)
        • 例如:map.get('W'),可取得 W 字母的出現次數


  • 補充
    • 三元運算子簡寫,將 if 與 else 簡寫成一行
      • 變數 = 條件運算式?符合條件執行此處:不符合條件執行此處
      • 執行結果會指派給變數

找最大值

  • Collections 
    • 是 Collection(interface) 的外包類別
    • 所有方法都是 static,不用 new 就可直接使用
    • 可用來處理集合(Set, List, Map)
    • https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html
  • 使用 Collections.max()找最大值

輸出

  • 由大至小印出
    • 使用 for 迴圈,初始值為 max 最大值,逐一遞減
    • 準備逐一尋找,字母出現次數 跟 count 變數相同的字母


  • 使用 foreach 讀取 map
    • for(元素資料型別 變數名稱 : 集合){}
    • for(Character letter : map.keySet()) {}
      • 這邊的 keySet() 就是指測試資料句子中出現的字母們(不重複)
      • 取得字母的出現次數:使用 map.get('W'),可取得 W 字母出現的次數
      • 判斷每一個字母出現次數與 for 迴圈的 count 變數是否相等
        • 若相等而印出字母與 count 變數

   👉  CPE 一顆星選集列表(49題) 題目說明與解答

留言

這個網誌中的熱門文章

CPE 一顆星選集題目說明與解答 - Java 筆記與心得分享

Visual Studio 自動排版格式化程式碼

1. Vito's family (CPE10406, UVA10041) - CPE一顆星解答與說明