🔍 2025藍橋杯備賽Day7——B2117 整理藥名
題目難度:?? 適合掌握字符串基礎操作
考察重點:大小寫轉換、字符串遍歷、邊界條件處理
B2117 整理藥名
題目描述
醫生在書寫藥品名的時候經常不注意大小寫,格式比較混亂。現要求你寫一個程序將醫生書寫混亂的藥品名整理成統一規范的格式,即藥品名的第一個字符如果是字母要大寫,其他字母小寫。
如將 ASPIRIN 、 aspirin 整理成 Aspirin。
輸入格式
第一行一個數字 n n n,表示有 n n n 個藥品名要整理, n n n 不超過 100 100 100。
接下來 n n n 行,每行一個單詞,長度不超過 20 20 20,表示醫生手書的藥品名。
藥品名由字母、數字和 - 組成。
輸出格式
n n n 行,每行一個單詞,對應輸入的藥品名的規范寫法。
輸入輸出樣例 #1
輸入 #1
4
AspiRin
cisapride
2-PENICILLIN
Cefradine-6
輸出 #1
Aspirin
Cisapride
2-penicillin
Cefradine-6
🔥 解法一:直接遍歷法(推薦)
🛠? 實現思路
分步處理:
- 首字符特殊處理(大寫轉換)
- 其余字符統一轉小寫
#include <iostream>
#include <cctype>
using namespace std;int main() {int n;cin >> n;cin.ignore(); // 忽略第一行末尾的換行符while (n--) {string s;getline(cin, s); // 讀取整行(兼容含空格的輸入)if (!s.empty()) {// 處理首字符if (isalpha(s[0])) {s[0] = toupper(s[0]);}// 處理其余字符for (int i = 1; i < s.size(); ++i) {if (isalpha(s[i])) {s[i] = tolower(s[i]);}}}cout << s << endl;}return 0;
}
🔥 解法二:函數封裝法(工程級)
🛠? 實現思路
模塊化設計:
- 將處理邏輯封裝為獨立函數
- 提升代碼復用性和可測試性
#include <iostream>
#include <cctype>
using namespace std;// 規范藥品名
string formatDrugName(string s) {if (!s.empty()) {// 首字母大寫if (isalpha(s[0])) {s[0] = toupper(s[0]);}// 其余字母小寫for (int i = 1; i < s.size(); ++i) {if (isalpha(s[i])) {s[i] = tolower(s[i]);}}}return s;
}int main() {int n;cin >> n;cin.ignore(); // 處理輸入緩沖while (n--) {string s;getline(cin, s);cout << formatDrugName(s) << endl;}return 0;
}
📚 知識點總結
一、關鍵庫函數
-
isalpha()
int isalpha(int c); // 判斷字符是否為字母(A-Z, a-z)
-
toupper() / tolower()
int toupper(int c); // 轉大寫(僅對小寫字母有效) int tolower(int c); // 轉小寫(僅對大寫字母有效)
二、邊界處理
- 空字符串處理:
if (!s.empty())
避免越界訪問 - 非字母字符保留:數字、
-
不參與轉換
🚨 常見錯誤警示
錯誤1:未處理輸入緩沖
cin >> n;
// 錯誤:未處理換行符,導致getline讀取空行
修正:
cin >> n;
cin.ignore(); // 清除輸入緩沖區中的換行符
錯誤2:錯誤轉換非字母字符
// 錯誤:未判斷直接轉換
s[i] = tolower(s[i]); // 可能將數字或符號錯誤處理
修正:
if (isalpha(s[i])) {s[i] = tolower(s[i]);
}
錯誤3:忽略首字符非字母情況
// 錯誤:強制轉換首字符
s[0] = toupper(s[0]); // 若首字符是數字,導致錯誤
修正:
if (isalpha(s[0])) {s[0] = toupper(s[0]);
}
🌟 舉一反三
變種題1:首字母與尾字母大寫
// 若要求首字母和尾字母大寫(若為字母)
if (!s.empty()) {if (isalpha(s[0])) s[0] = toupper(s[0]);if (isalpha(s.back())) s.back() = toupper(s.back());
}
變種題2:連字符后首字母大寫
// 將連字符后的字母大寫(如"pan-adol" → "pan-Adol")
for (int i = 1; i < s.size(); ++i) {if (s[i-1] == '-' && isalpha(s[i])) {s[i] = toupper(s[i]);}
}
🛠? 實戰技巧
1. 輸入優化
// 使用快速IO(關閉同步流)
ios::sync_with_stdio(false);
cin.tie(nullptr);
2. 內存預分配
s.reserve(20); // 根據題目最大長度預分配
3. 調試輸出
// 打印處理前后對比
cout << "原始:" << s << " → 處理:" << formatDrugName(s) << endl;
藍橋杯考場策略:
- 優先選擇解法一:代碼緊湊,適合快速實現
- 注意輸入緩沖處理:使用
cin.ignore()
避免讀取錯誤 - 邊界測試:測試首字符為數字、全大寫等情況
👉 思考題:若要求所有元音字母大寫,輔音字母小寫,如何修改代碼? 答案提示:
bool isVowel(char c) {c = tolower(c);return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
}// 在轉換邏輯中添加元音判斷
if (isVowel(s[i])) {s[i] = toupper(s[i]);
} else {s[i] = tolower(s[i]);
}