## 1128 正課作業6 ![12.16](https://hackmd.io/_uploads/rylemvrQJg.png) ![12.30](https://hackmd.io/_uploads/HyxlXwHmyx.png) ![13.4](https://hackmd.io/_uploads/BkelmDH7Je.png) ![13.5](https://hackmd.io/_uploads/B1CmQvBQ1x.png) ![13.7](https://hackmd.io/_uploads/H1B_7wHmyg.png) --- ## 12.16 (替換文字)範例程式12.16 Replacetext.java替換原始檔的文字,並將更改後的結果儲存於新的檔案中。請修改此程式,將更改後的結果儲存回原始檔案,呼叫 ```java java Exercise12_16 file oldString newString ``` 會將原始檔裡的oldString 換成 newString ```java import java.io.*; import java.util.*; public class ReplaceText { public static void main(String[] args) throws Exception { // 檢查命令列參數是否正確 if (args.length != 3) { System.out.println("Usage: java ReplaceText sourceFile targetFile oldStr newStr"); System.exit(1); // 如果參數數量不正確,程式退出 } // 檢查原始檔案是否存在 File sourceFile = new File(args[0]); if (!sourceFile.exists()) { System.out.println("Source file " + args[0] + " does not exist"); System.exit(2); // 如果原始檔案不存在,程式退出 } // 創建一個臨時檔案 File tempFile = new File(sourceFile.getAbsolutePath() + ".tmp"); try ( // 使用 Scanner 讀取原始檔案,PrintWriter 寫入臨時檔案 Scanner input = new Scanner(sourceFile); PrintWriter output = new PrintWriter(tempFile); ) { while(input.hasNext()) { String s1 = input.nextLine(); // 逐行讀取原始檔案 String s2 = s1.replaceAll(args[1], args[2]); // 替換舊字串為新字串 output.println(s2); // 將結果寫入臨時檔案 } } // 刪除原始檔案 if(!sourceFile.delete()) { System.out.println("刪除原始檔案失敗"); System.exit(3); // 如果刪除失敗,程式退出 } // 將臨時檔案重新命名為原始檔案 if(!tempFile.renameTo(sourceFile)) { System.out.println("重新命名臨時檔案失敗"); System.exit(4); } // 替換完成提示 System.out.println("替換完成,結果已儲存到 " + sourceFile.getName()); } } ``` --- ## 12.30 請撰寫一個程式,提示使用者輸入一個檔案名稱,並顯示檔案中每個字母(A-Z 和 a-z)出現的次數。程式區分大小寫。最後將每個字母的出現次數列出。以下是輸出結果的範本。 ```java Enter a filename:Lincoln.txt Number of A's: 56 Number of B's: 134 ... Number of Z's: 9 ``` ### 字母索引對應表 | 類型 | 字母範圍 | 索引範圍 | 索引計算方式 | |------------|----------|----------------------|----------------| | 大寫字母 | A - Z | 0 - 25 | `c - 'A'` | | 小寫字母 | a - z | 26 - 51 | `c - 'a' + 26` | --- ### 範例計算 | 字母 | 類型 | 索引計算 | 結果 | |------|------------|-----------------------|------| | A | 大寫字母 | `'A' - 'A'` | 0 | | Z | 大寫字母 | `'Z' - 'A'` | 25 | | a | 小寫字母 | `'a' - 'a' + 26` | 26 | | z | 小寫字母 | `'z' - 'a' + 26` | 51 | | 陣列位置 | 0 | 1 | 2 | 3 | ... | 26 | 27 | 28| |--- |--- |---|---|---|--- |---|---|---| | 字母位置 | A | B | C | D | ... | a | b | c | | 次數 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | --- 程式碼 ```java import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class homework12_30 { public static void main(String[] args) { // 建立一個陣列來統計每個字母的出現次數 // letterCount[0-25] 用於記錄 A-Z 的次數 // letterCount[26-51] 用於記錄 a-z 的次數 int[] letterCount = new int[52]; // 提示使用者輸入檔案名稱 Scanner input = new Scanner(System.in); // 用於讀取使用者輸入 System.out.print("Enter a filename: "); // 提示訊息 String filename = input.nextLine(); // 接收使用者輸入的檔案名稱 try { // 嘗試讀取使用者指定的檔案 File file = new File(filename); // 創建 File 物件 Scanner fileScanner = new Scanner(file); // 用於逐行讀取檔案內容 // 逐行讀取檔案內容 while (fileScanner.hasNextLine()) { // 如果還有下一行,繼續處理 String line = fileScanner.nextLine(); // 讀取當前行 // 遍歷當前行的每個字元 for (char c : line.toCharArray()) { if (c >= 'A' && c <= 'Z') { // 如果是大寫字母 'A' 的 ASCII 值是 65,'Z' 的 ASCII 值是 90 letterCount[c - 'A']++; // 計算 A-Z 的出現次數 } else if (c >= 'a' && c <= 'z') { // 如果是小寫字母 letterCount[c - 'a' + 26]++; // 計算 a-z 的出現次數 } } } fileScanner.close(); // 關閉檔案掃描器 // 顯示每個字母的次數(只顯示出現過的字母) for (int i = 0; i < 26; i++) { // 遍歷大寫字母 A-Z if (letterCount[i] > 0) { // 如果該字母出現過 System.out.println("Number of " + (char) ('A' + i) + "'s: " + letterCount[i]); } } for (int i = 0; i < 26; i++) { // 遍歷小寫字母 a-z if (letterCount[i + 26] > 0) { // 如果該字母出現過 System.out.println("Number of " + (char) ('a' + i) + "'s: " + letterCount[i + 26]); } } } catch (FileNotFoundException e) { // 如果檔案找不到 System.out.println("File not found: " + filename); // 顯示錯誤訊息 } input.close(); // 關閉使用者輸入的掃描器 } } ``` Lincoln.txt範例 ``` aaaaaBBBBBGGGGGHHHHHJJJJJ Lllllooooovvvvveeeee A B C D e f g h ``` netbean可能會找不到 ```java (base) rain@MacBook-Air Desktop %java homwwork12_30.java Enter a filename: Lincoln.txt Number of A's: 1 Number of B's: 6 Number of C's: 1 Number of D's: 1 Number of G's: 5 Number of H's: 5 Number of J's: 5 Number of L's: 1 Number of a's: 5 Number of e's: 6 Number of f's: 1 Number of g's: 1 Number of h's: 1 Number of l's: 4 Number of o's: 5 Number of v's: 5 ``` --- ## 13.4 (顯示日曆) 請重新撰寫範例程式 6.12 的 PrintCalendar 類別,利用 Calendar 及 GregorianCalendar 類別,為特定月份顯示日曆內容。此程式應從指令列取得月份與年份資訊。比方說: ```java java Exercise13_04 5 2016 ``` ``` May, 2016 Sun Mon Tue Wed Thu Fri Sat 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 ``` 使用 GregorianCalendar 類別的內建方法,直接獲取: 當月的起始星期 (Calendar.DAY_OF_WEEK)。 當月的天數 (calendar.getActualMaximum(Calendar.DAY_OF_MONTH))。 ```java import java.util.Calendar; import java.util.GregorianCalendar; public class PrintCalendar { /** 主方法 */ public static void main(String[] args) { // 檢查是否提供了年份和月份 if (args.length != 2) { System.out.println("用法: java PrintCalendar <月份> <年份>"); System.exit(1); } int month = Integer.parseInt(args[0]); // 月份 int year = Integer.parseInt(args[1]); // 年份 // 檢查月份範圍 if (month < 1 || month > 12) { System.out.println("月份必須在 1 到 12 之間"); System.exit(2); } // 顯示日曆 printMonth(year, month); } /** 顯示指定年份和月份的日曆 */ public static void printMonth(int year, int month) { // 打印日曆標題 printMonthTitle(year, month); // 打印日曆主體 printMonthBody(year, month); } /** 打印日曆標題 */ public static void printMonthTitle(int year, int month) { System.out.println(" " + getMonthName(month) + ", " + year); System.out.println("-----------------------------"); System.out.println(" Sun Mon Tue Wed Thu Fri Sat"); } /** 獲取月份名稱 */ public static String getMonthName(int month) { String[] monthNames = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; return monthNames[month - 1]; } /** 打印日曆主體 */ public static void printMonthBody(int year, int month) { // 使用 GregorianCalendar 獲取當月的第一天和總天數 GregorianCalendar calendar = new GregorianCalendar(year, month - 1, 1); int startDay = calendar.get(Calendar.DAY_OF_WEEK); // 星期幾 int numberOfDaysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); // 總天數 // 填充空白 for (int i = 1; i < startDay; i++) { System.out.print(" "); } // 打印每一天 for (int i = 1; i <= numberOfDaysInMonth; i++) { System.out.printf("%4d", i); if ((i + startDay - 1) % 7 == 0) { // 每 7 天換行 System.out.println(); } } System.out.println(); } } ``` ```java (base) rain@MacBook-Air homework6 % java PrintCalendar.java 5 2016 May, 2016 ----------------------------- Sun Mon Tue Wed Thu Fri Sat 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 ``` --- ## 13.5 --- ## 13.7 ---