String (chuỗi ký tự)
- Độ khó
- ★★☆☆☆ Dễ
- Thời lượng
- Khoảng 90 phút
- Học trước
- Vector
- Chủ đề
- stringxâu ký tự
- Trạng thái
Kiến thức cơ bản
String trong C++ được sử dụng để lưu chuỗi (xâu) ký tự, nó như một mảng char động, có thể thay đổi kích thước một cách linh hoạt cũng như hỗ trợ chèn, xóa, sửa đổi...
Để sử dụng thự viện string, ta thêm vào đầu chương trình:
#include <string> // Khai báo thư viện chứa string
Khai báo
string s; // Khai báo biến s kiểu string
// Khai báo biến greeting kiểu string và gán giá trị “Hello”
string greeting = "Hello";
//Khai báo biến s kiểu string, gán giá trị “1234”, không phải số 1234
string s = "1234";
Nhập, xuất, duyệt chuỗi
Sử dụng cin chỉ cho phép đọc một dãy gồm các ký tự liền nhau (không có khoảng trắng), nên nó sẽ trả về các ký tự đến khoảng trắng đầu tiên trong chuỗi.
Để nhập chuỗi có khoảng trắng, ta sử dụng hàm getline(). Lưu ý chèn thêm lệnh cin.ignore() trước getline() sau lệnh cin để tránh getline chỉ nhận phím Enter.
getline(cin, s); // Nhập một dòng, kể cả dòng có nhiều dấu khoảng trắng
Để xuất một chuỗi, ta dùng cout:
cout <<s <<endl; //Xuất chuỗi s ra màn hình rồi xuống dòng
Vì string tương tự như mảng động (vector) các ký tự, ta có thể truy xuất các ký tự trong xâu thông qua chỉ số (từ 0) hoặc duyệt bằng ranged-base for loop.
Phương thức length(), size() cho biết chiều dài của chuỗi:
s.length(); // trả về độ dài chuỗi s, ví dụ s="Hello" thì s.length()=5
s.size(); // trả về độ dài của chuỗi s
Một số phương thức thông dụng với chuỗi
Tương tự như vector, với chuỗi ta cũng sử dụng được các phương thức: push_back(c), pop_back(), back(), front(),…
Hàm insert() để chèn ký tự c, hoặc chuỗi ký tự vào xâu s, theo các cách:
s.insert(pos, c); // chèn ký tự c vào vị trí pos của xâu s
s.insert(pos, n, c); // chèn n ký tự c vào vị trí pos của xâu s
s1.insert(pos, s2); // chèn xâu s2 vào vị trí pos của xâu s1
s1.insert(pos, s2, idx, n); // chèn n ký tự từ idx của chuỗi s2 vào s1
Hàm erase() sử dụng để xóa toàn bộ hoặc một phần của chuỗi, theo các cách:
s.erase(); // xoá mọi ký tự của chuỗi
s.erase(pos); // xoá các ký tự từ vị trí pos đến cuối
s.erase(pos, k); // xoá k ký tự từ vị trí pos
Hàm replace() sử dụng để thay thế một hoặc nhiều ký tự:
s.replace(pos, n, m, c) // Thay thế n ký tự từ vị trí pos bằng m ký tự c
s1.replace (pos, n, s2) // Thay thế n ký tự từ vị trí pos bằng s2
// Thay thế n ký tự từ pos1 của s1 bằng m ký tự của s2 từ pos1
s1.replace (pos1, n, s2, pos2, m)
Sử dụng hàm find() để tìm kiếm chuỗi con (có thể chỉ là ký tự) trong chuỗi s.
s.find(sub); // Trả về vị trí xuất hiện đầu tiên của chuỗi sub trong s
// Nếu không tìm thấy, trả về string::npos
s.find(sub, pos); // Bắt đầu tìm kiếm từ vị trí pos (mặc định pos = 0)
s.find(sub, pos, n); // tìm n ký tự đầu tiên của chuỗi con
Hàm substr() được sử dụng để trích xuất một chuỗi con từ chuỗi đã cho.
s.substr(pos); // Tạo chuỗi con từ vị trí pos đến cuối chuỗi s
s.substr(pos, len); // Tạo chuỗi con của s gồm len ký tự từ vị trí pos
Chuyển số thành chuỗi và ngược lại
Chuyển chuỗi thành kiểu int (convert string to integer):
int i = stoi(s); // chuyển chuỗi s thành số và gán vào biến i kiều int
Một số hàm khác như: stof(s) - string to float; stol(s) - string to long; stoll(s) - string to long long;
Để biến một số thành chuỗi ta dùng hàm to_string(i).
string s = to_string(i); // chuyển số i thành chuỗi và gán vào biến s
Luyện tập
Bài 1. Vườn hoa nguyên âm
Hùng đang tập đọc. Mẹ bảo Hùng đếm xem một câu có bao nhiêu nguyên âm (a, e, i, o, u). Bạn hãy giúp Hùng kiểm tra kết quả bằng máy tính nhé.
| Đầu vào | Một dòng duy nhất chứa chuỗi ký tự s (1 ≤ |s| ≤105) gồm chữ cái và khoảng trắng. | |
|---|---|---|
| Đầu ra | Số nguyên duy nhất là số lượng nguyên âm tìm thấy trong chuỗi. | |
| Test | Input | Output |
| hello world | 3 | |
Bài 2. Mật mã đối xứng (Palindrome)
Một từ được gọi là "đối xứng" nếu đọc xuôi hay đọc ngược đều hoàn toàn giống hệt nhau (Ví dụ: radar, madam, level, 123321). Bạn hãy kiểm tra xem từ bí mật có phải là mật mã đối xứng không?
| Đầu vào | Chuỗi ký tự s (1 ≤ |s| ≤105) gồm chữ cái, chữ số | |
|---|---|---|
| Đầu ra | In ra YES nếu chuỗi đối xứng, ngược lại in ra NO | |
| Test | Input | Output |
| rotator | YES | |
| coder | NO | |
Bài 3. Giải cứu robot
Chú robot thám hiểm bị nhiễm virus và nhận lệnh theo chiều ngược lại. Để giúp robot đi đúng đường, bạn cần lật ngược toàn bộ chuỗi ký tự mệnh lệnh trước khi nạp vào bộ điều khiển!
| Đầu vào | Chuỗi ký tự s (1 ≤ |s| ≤105) | |
|---|---|---|
| Đầu ra | Chuỗi s sau khi đã đảo ngược từ ký tự cuối cùng về ký tự đầu tiên | |
| Test | Input | Output |
| Hello World | dlroW olleH | |
Bài 4. Bảng tên viết hoa
Nhà trường muốn in khẩu hiệu lên băng rôn bằng chữ in hoa. Hãy đổi mọi chữ cái thường trong dòng chữ sang chữ hoa. Các ký tự khác (chữ số, dấu cách, dấu câu) giữ nguyên.
| Đầu vào | Chuỗi ký tự s trên một dòng (dài không quá 1000 ký tự). | |
|---|---|---|
| Đầu ra | Chuỗi s sau khi chuyển sang chữ hoa. | |
| Test | Input | Output |
| Hello World 123 | HELLO WORLD 123 | |
Bài 5. Tổng chữ số của số khổng lồ
Ở xứ sở Số Lớn có những con số dài đến hàng trăm nghìn chữ số, lớn đến mức int và long long đều không chứa nổi. Hãy tính tổng các chữ số của một số như vậy.
| Đầu vào | Một số lớn có thể có đến hàng trăm nghìn chữ số. | |
|---|---|---|
| Đầu ra | Tổng các chữ số của số nhập vào | |
| Test | Input | Output |
| 909090 | 27 | |
Bài 6. Chữ cái được yêu thích nhất
Cô giáo muốn thống kê xem trong một bài văn, chữ cái nào xuất hiện nhiều nhất. Nếu có nhiều chữ cái cùng xuất hiện nhiều nhất, hãy chọn chữ đứng trước trong bảng chữ cái. Quỳnh Vy giúp cô nào?
| Đầu vào | Chuỗi s gồm các chữ cái thường, không có dấu cách (|s| ≤ 105). | |
|---|---|---|
| Đầu ra | Chữ cái xuất hiện nhiều nhất và số lần xuất hiện, cách nhau một dấu cách. | |
| Test | Input | Output |
| banana | a 3 | |
| abcabc | a 2 | |
Bài 7. Bài toán chia hết
Cho số n (có tối đa 1000 chữ số), hãy kiểm tra n có chia hết cho 3, 7, 11 hay không?
| Đầu vào | Cho số n (có tối đa 1000 chữ số) | |
|---|---|---|
| Đầu ra | In ra trên 1 lần lượt YES hoặc NO nếu n chia hết cho 3, 7, 11. | |
| Test | Input | Output |
| 234 | YES NO NO | |
| 25666641 | YES YES YES | |
Bài 8. Cộng hai số khổng lồ
Hai số nguyên dương có đến 1000 chữ số, không kiểu số nào chứa nổi. Hãy cộng chúng theo cách cộng đặt tính ở tiểu học: cộng từ phải sang trái và nhớ sang hàng bên cạnh. Gợi ý: đảo ngược hai chuỗi, cộng từng chữ số kèm biến nhớ, cuối cùng đảo ngược kết quả. Đừng quên phần nhớ còn dư ở cuối.
| Đầu vào | Dòng 1: số thứ nhất. Dòng 2: số thứ hai. (Độ dài không quá 1000) | |
|---|---|---|
| Đầu ra | Tổng của hai số | |
| Test | Input | Output |
| 999999999 1 | 1000000000 | |
Bài tập tự luyện
Bài 1. Tìm kho báu
Nhà thám hiểm có một tấm bản đồ ghi bằng chuỗi s và mật khẩu kho báu là chuỗi t. Kho báu nằm ở nơi mật khẩu t xuất hiện đầu tiên trong bản đồ. Hãy chỉ ra vị trí đó (tính từ 0). Gợi ý: dùng hàm find.
| Đầu vào | Dòng 1: chuỗi s; Dòng 2: chuỗi t (s, t gồm chữ cái thường, không có dấu cách có độ dài không quá 1000). | |
|---|---|---|
| Đầu ra | Vị trí đầu tiên t xuất hiện trong s (tính từ 0). Nếu không có thì in -1. | |
| Test | Input | Output |
| abracadabra cad | 4 | |
| abracadabra xyz | -1 | |
Bài 2. Đếm từ trong câu
Cô giáo chấm bài tập làm văn và muốn đếm số từ trong câu, nhưng các bạn hay gõ thừa dấu cách (ở đầu câu, cuối câu, hoặc nhiều dấu cách liền nhau). Một từ là dãy ký tự liên tiếp không chứa dấu cách.
| Đầu vào | Một dòng gồm chữ cái và dấu cách độ dài ≤ 105 (dùng getline). | |
|---|---|---|
| Đầu ra | Số từ trong dòng. | |
| Test | Input | Output |
| xin chao cac ban | 4 | |
- Gợi ý: dùng stringstream của thư viện <sstream> để loại khoảng trắng.
Bài 3. Đảo kiểu chữ
Máy in bị lỗi: chữ hoa in thành chữ thường và chữ thường in thành chữ hoa. Hãy mô phỏng lỗi này. Các ký tự không phải chữ cái giữ nguyên.
| Đầu vào | Một dòng gồm chữ cái và dấu cách độ dài ≤ 103 (dùng getline). | |
|---|---|---|
| Đầu ra | Dòng sau khi đảo kiểu chữ. | |
| Test | Input | Output |
| HeLLo 2026 | hEllO 2026 | |
Bài 4. Mật mã Caesar
Hoàng đế Caesar mã hóa thư bằng cách dịch mỗi chữ cái đi k vị trí trong bảng chữ cái, theo vòng tròn: sau z lại quay về a. Ví dụ với k = 3 thì a thành d, b thành e, z thành c. Hãy mã hóa bức thư của Caesar.
| Đầu vào | Dòng 1: chuỗi chữ cái thường, không có dấu cách. Dòng 2: số nguyên k. (Độ dài chuỗi không quá 105; 0 ≤ k ≤ 1000) | |
|---|---|---|
| Đầu ra | Chuỗi sau khi mã hóa. | |
| Test | Input | Output |
| abz 3 | dec | |
Bài 5. Nén chuỗi
Để tiết kiệm bộ nhớ, ta nén chuỗi bằng cách thay mỗi đoạn các ký tự giống nhau liên tiếp bằng ký tự đó kèm độ dài đoạn. Ví dụ aaabbc được nén thành a3b2c1.
| Đầu vào | Chuỗi chữ cái thường, không có dấu cách độ dài không quá 105 | |
|---|---|---|
| Đầu ra | Chuỗi đã nén | |
| Test | Input | Output |
| aaaaaaaaaaaab | a12b1 | |
Bài 6. Hai từ "đảo chữ"
Hai từ được gọi là đảo chữ (anagram) của nhau nếu xếp lại các chữ cái của từ này thì được từ kia, ví dụ listen và silent. Hãy kiểm tra hai từ cho trước. Gợi ý: dùng mảng đếm 26 chữ cái.
| Đầu vào | Dòng 1: từ thứ nhất. Dòng 2: từ thứ hai. (Độ dài không quá 105) | |
|---|---|---|
| Đầu ra | In YES nếu hai từ là đảo chữ của nhau, ngược lại in NO | |
| Test | Input | Output |
| listen silent | YES | |
| hello world | NO | |
Bài 7. Từ dài nhất
Hùng có danh sách n từ và muốn tìm ra từ dài nhất. Nếu có nhiều từ dài bằng nhau thì chọn từ xuất hiện đầu tiên.
| Đầu vào | Dòng 1: số nguyên n (1 ≤ n ≤ 1000). Dòng 2: n từ chữ thường, cách nhau bởi dấu cách, mỗi từ không quá 100 ký tự. | |
|---|---|---|
| Đầu ra | Từ dài nhất | |
| Test | Input | Output |
| 4 an binh minh nang | binh | |
Bài 8. Số chia hết cho 13
Cho số n (có tối đa 1000 chữ số), hãy kiểm tra n có chia hết cho 13 hay không?
| Đầu vào | Cho số n (có tối đa 1000 chữ số) | |
|---|---|---|
| Đầu ra | In ra YES nếu n chia hết cho 13, ngược lại in ra NO | |
| Test | Input | Output |
| 26 | YES | |
| 14 | NO | |