
Buổi 28: Xử Lý Xâu Ký Tự (String)¶
I. Lý Thuyết¶
Trong bài trước, ta đã làm quen với việc nhập/xuất và truy xuất các ký tự trong xâu (string). Bài học này sẽ tập trung vào các kỹ thuật Xử lý xâu (String Manipulation) thường gặp nhất: Đếm ký tự, chuyển đổi Hoa/Thường, và Chuẩn hóa chuỗi.
1. Kỹ Thuật Đếm Ký Tự Đặc Biệt¶
Để đếm một loại ký tự nào đó (ví dụ: đếm chữ 'a', đếm khoảng trắng, đếm chữ số), ta dùng vòng lặp duyệt mảng kết hợp với câu lệnh if.
Ví dụ đếm khoảng trắng (Space):
int count = 0;
for (int i = 0; i < s.length(); i++) {
if (s[i] == ' ') { // ' ' la ky tu khoang trang (nhay don)
count++;
}
}
Ví dụ đếm chữ số (từ '0' đến '9'):
Lưu ý: Không viết s[i] == 0 (đây là số nguyên), mà phải viết s[i] >= '0' && s[i] <= '9' (So sánh trong bảng mã ASCII).
2. Chuyển Đổi Hoa / Thường¶
Trong C++, mỗi ký tự có một mã số (Mã ASCII). Ví dụ 'A' có mã là 65, 'a' có mã là 97.
Thay vì nhớ mã số phức tạp, ta sử dụng thư viện <cctype> (C Character Types) được hỗ trợ sẵn.
toupper(c): Chuyển ký tựcthành CHỮ HOA.tolower(c): Chuyển ký tựcthành chữ thường.- Lưu ý quan trọng: Hàm này chỉ trả về kết quả mới chứ không làm thay đổi biến gốc. Phải gán lại:
s[i] = toupper(s[i]);
#include <iostream>
#include <string>
#include <cctype> // Thu vien xu ly ky tu
using namespace std;
int main() {
string s = "aPple";
s[0] = toupper(s[0]); // Chuyen 'a' thanh 'A'
s[1] = tolower(s[1]); // Chuyen 'P' thanh 'p'
cout << s; // In ra: Apple
return 0;
}
3. Chuẩn Hóa Chuỗi Cơ Bản¶
Bài toán "Chuẩn hóa tên" là bài toán kinh điển nhất trong xử lý String. Một cái tên đẹp phải thỏa mãn:
- Không có khoảng trắng thừa ở ĐẦU và CUỐI xâu.
- Không có khoảng trắng thừa Ở GIỮA các từ.
- Chữ cái đầu tiên của mỗi từ phải Viết Hoa, các chữ còn lại viết thường.
Kỹ thuật xóa ký tự thừa:
Trong thư viện <string>, ta có hàm s.erase(vị_trí, số_lượng).
- Xóa 1 ký tự tại vị trí
i:s.erase(i, 1); - Vì thao tác xóa sẽ làm mảng bị thụt lại (Dịch trái), nên ta phải dùng
i--để lùi lại kiểm tra giống hệt bài mảng 1 chiều.
II. Bài Tập Thực Hành Tại Lớp¶
Bài 1: Đếm Nguyên Âm¶
Đề bài: Nhập vào một xâu ký tự (viết thường). Đếm xem có bao nhiêu Nguyên Âm trong xâu đó. Các nguyên âm trong tiếng Anh bao gồm: a, e, i, o, u (Mẹo nhớ: U-E-O-A-I).
Gợi ý code
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
cout << "Nhap xau: ";
getline(cin, s);
int count = 0;
for (int i = 0; i < s.length(); i++) {
if (s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u') {
count++;
}
}
cout << "So luong nguyen am: " << count << endl;
return 0;
}
Bài 2: Chuyển Toàn Bộ Chuỗi Thành Chữ Hoa¶
Đề bài: Nhập vào một xâu bất kỳ. Hãy chuyển TẤT CẢ các chữ cái trong xâu thành Chữ In Hoa, sau đó in chuỗi mới ra màn hình.
Gợi ý code
III. Bài Tập Về Nhà¶
Bài 1: Đếm Số Từ Trong Chuỗi¶
Đề bài: Nhập vào một xâu \(S\) gồm các từ cách nhau bởi DẤY CÁCH (Khoảng trắng). Giả sử xâu đã được nhập đúng chuẩn (Không có khoảng trắng thừa ở đầu/cuối, và giữa các từ chỉ có đúng 1 khoảng trắng). Hãy in ra số lượng TỪ có trong xâu đó. (Gợi ý: Số từ = Số lượng khoảng trắng + 1).
Bài 2: Xóa Khoảng Trắng Thừa Ở Đầu Và Cuối¶
Đề bài: Nhập vào một xâu có chứa nhiều khoảng trắng thừa ở ĐẦU và CUỐI xâu. Hãy dùng hàm s.erase() để xóa chúng. In ra xâu kết quả (được bọc trong cặp dấu ngoặc vuông [ ] để chứng minh đã xóa sạch).
*(Gợi ý:
- Xóa đầu: Dùng vòng lặp
while(s[0] == ' ') s.erase(0, 1); - Xóa cuối: Dùng vòng lặp
while(s[s.length() - 1] == ' ') s.erase(s.length() - 1, 1);)*
Bài 3: Sửa Tên Chuẩn Viết Hoa (Khó)¶
Đề bài: Nhập vào một cái tên (Giả sử không có khoảng trắng thừa).
Nhưng người dùng lại nhập hoa/thường lẫn lộn (VD: nGuyen vaN a).
Hãy chuẩn hóa: Chữ cái đầu của mỗi từ phải là Chữ Hoa, các chữ cái còn lại trong từ phải là chữ thường \(\to\) Nguyen Van A.
*(Gợi ý:
- Đầu tiên, chuyển TẤT CẢ về chữ thường
tolower(). - Chữ cái vị trí
s[0]luôn luôn viết hoatoupper(). - Chạy vòng lặp từ 1 đến hết. Nếu phát hiện
s[i] == ' '(khoảng trắng), thì chữ cái ngay đằng sau nó làs[i+1]bắt buộc phải viết hoa).*
Bài 4: Kiểm Tra Mật Khẩu Mạnh¶
Đề bài: Nhập vào 1 xâu là Mật Khẩu. Một mật khẩu mạnh phải thỏa mãn ĐỒNG THỜI 3 điều kiện:
- Chiều dài phải từ 8 ký tự trở lên.
- Có ít nhất 1 chữ số.
- Có ít nhất 1 chữ cái in hoa. In ra "Manh" nếu thỏa mãn cả 3, ngược lại in "Yeu".
IV. Ghi Chú Quan Trọng¶
So Sánh Mã ASCII¶
Mỗi ký tự đều được máy tính hiểu như một con số nguyên. Bảng mã ASCII quy định:
'A'= 65,'B'= 66 ...'Z'= 90'a'= 97,'b'= 98 ...'z'= 122'0'= 48,'1'= 49 ...'9'= 57
Khoảng cách giữa CHỮ HOA và CHỮ THƯỜNG tương ứng của nó luôn luôn là 32.
Do đó, ngoài hàm toupper(), ta có thể chuyển s[i] đang là chữ thường thành hoa bằng phép toán: s[i] = s[i] - 32; (Vì 97 - 32 = 65).
Dĩ nhiên, dùng thư viện <cctype> vẫn an toàn và chuyên nghiệp hơn!
V. Ôn Tập Trắc Nghiệm¶
Kiểm tra kỹ năng Xử lý Chuỗi: