You are on page 1of 58

Tuesday, October 24, 2023  06:34:34 AM

XÂ U KÝ TỰ
Khai bá o xâ u
Cá c phép toá n xử lý xâ u
Mộ t số bà i toá n

© Lê Minh Hoà ng. All Rights Reserved.


Xâ u ký tự
Mộ t dãy cá c ký tự liên tiếp
Xâ u có thể rỗ ng (gồ m 0 ký tự )
Mỗ i ký tự cũ ng đượ c coi là mộ t xâ u gồ m
đú ng 1 ký tự đó
Khai bá o xâ u ký tự
Khai bá o sử dụ ng thư viện #include
<string>
string (chú ý khô ng phả i
using
cstring)
namespace std;
Kiểu dữ liệu cho xâ u ký tự
là std::string string s =
"Hello";
3
Cá ch viết hằ ng xâ u ký tự
#include <iostream>
Viết cá c ký tự nằ m trong #include <string>
using namespace std;
dấ u nháy kép int main()
{
Cá c ký tự đặ c biệt đượ c string s = "CHXHCNVN\nDL-
TD-HP";
chấ p nhậ n như bả ng ký cout << s;
}
tự đặ c biệt Kết quả in ra:
CHXHCNVN
DL-TD-HP
4
Bả ng mã ký tự đặ c biệt
Mã C++ Tên ký tự Mã ASCII
\n Xuố ng dò ng 10 hoặ c 13+10
\r Về đầ u dò ng (Enter) 13
\t Tab 9
\v Tab dọ c
\b Lù i trá i (Backspace) 8
\f Hết form
\a alert (beep) 7
\' Nháy đơn ' 39
\" Nháy kép " 34
\? Dấ u hỏ i ? 63
\\ Dấ u sổ ngượ c \ 92

5
Bả n chấ t củ a kiểu std::string
std::string là mộ t lớ p, mỗ i biến kiểu #include
std::string là mộ t đố i tượ ng, bao gồ m cả dữ
liệu và cá c phương thứ c xử lý dữ liệu
<string>
Có thể coi s như mộ t mả ng cá c ký tự (char) using
Tuy nhiên khá c vớ i mả ng: namespace
std;
khô ng phả i địa chỉ củ a dãy ký tự đượ c lưu
cũ ng khô ng phả i địa chỉ củ a ký tự thứ
 Khô ng đượ c dù ng memset, fill_n, fill trự c tiếp
trên biến s mà phả i dù ng cá c phương thứ c đặ c
thù củ a std::string string s =
"Hello"; 6
Đọ c/in xâ u ký tự
Toá n tử << có thể dù ng để đẩy mộ t xâ u ký tự ra luồ ng xuấ t
Toá n tử >> có thể dù ng để đọ c mộ t xâ u khá c rỗ ng và khô ng
chứ a dấ u cá ch
Ví dụ
cin >> s;
cout << s;

7
Đọ c/in xâ u ký tự
Nếu muố n đọ c mộ t dò ng từ luồ ng nhậ p và o mộ t xâ u (có thể
dò ng chứ a dấ u cá ch)
Dù ng std::getline(stream, s, delim)
stream: Luồ ng nhậ p (cin, ifstream, …)
s: Xâ u ký tự
delim: Ký tự kết thú c dò ng, nếu khô ng chỉ ra delim, coi như
delim là ký tự xuố ng dò ng (\n)
8
#include <iostream> Full Name: James
#include <string> Bond
James Bond
using namespace std;
int main()
{
string name;
cout << "Full Name: ";
getline(cin, name);
cout << name;
}
9
#include <iostream> Full Name: James
#include <string> Bond
using namespace std; James
int main() Bond
{
string fname, lname;
cout << "Full name: ";
getline(cin, fname, ' ');
getline(cin, lname);
cout << fname << '\n' <<
lname;
}
10
Độ dà i xâ u
Hà m
Trả về số ký tự trong xâ u (độ dà i xâ u )
Hà m
Đặ t chiều dà i xâ u là
Nếu , máy sẽ thêm cá c ký tự và o cuố i xâ u cho đủ độ dà i , cá c ký tự thêm và o khô ng
xá c định (rá c)
Nếu , cá c ký tự cuố i xâ u sẽ bị cắ t bỏ cho vừ a độ dà i
Hà m
Giố ng như hà m , có điều cá c ký tự thêm và o cuố i xâ u (nếu có ) đượ c đặ t bằ ng ký tự
11
#include <iostream>
Tạ o mộ t xâ u
#include <string>
gồ m 1000 dấ u using namespace std;

*
int main()
{
string s = "";
s.resize(1000, '*');
cout << s << '\n';
cout << "Number of \"*\": " <<
s.length();
}
12
Truy cậ p ký tự
#include <iostream>
Cá c ký tự đượ c đá nh số #include <string>
using namespace std;
từ 0 tớ i string s = "I like to code
in C++";
: Ký tự thứ trong xâ u int main()
{
cout << s[5];
}
I l i k e t o c o d e i n C + +
0 1 2 3 4 5 6 7 8 ……………………………………………………… 20
13
Phép gá n xâ u
: Gá n xâ u bằ ng xâ u
Chú ý:
Máy phả i cấ p phá t bộ nhớ và copy cá c ký tự
từ xâ u sang xâ u (Độ phứ c tạ p tính toá n
bằ ng độ dà i xâ u )
14
Phép cộ ng xâ u
: Vớ i là hai xâ u, phép trả về xâ u tạ o thà nh bằ ng cá ch ghép
xâ u và o cuố i xâ u
Chú ý
Phép cộ ng xâ u khô ng có tính giao hoá n:
Có thể thự c hiện toá n tử +=: Viết thay cho
Máy phả i cấ p phá t bộ nhớ và copy cá c ký tự từ xâ u và sang
xâ u kết quả (Độ phứ c tạ p tính toá n bằ ng độ dà i xâ u kết quả )
15
#include <iostream>
#include <string>
using namespace std;
int main()
{
string a = "It's now";
string b = "or never";
string c = a + ' ' + b;
cout << c; //It's now or never
}
16
Thứ tự từ điển (lexicographical order)
Nguyên lý so sá nh hai xâ u và Chú ý: Tố c độ phép so sá nh phụ

So sá nh từ đầ u theo từ ng cặ p thuộ c và o vị trí đầ u tiên mà

ký tự ,
Nếu gặ p , kết luậ n ngay , stop "computer" > "calculator"
"COMPUTER" < "calculator"
Nếu gặ p , kết luậ n ngay , stop
"professional" < "professor"
Nếu khô ng thấy cặ p ký tự
"10" < "9"
tương ứ ng khá c nhau, xâ u
"with" < "without"
ngắ n hơn đượ c coi là nhỏ hơn
17
Phép so sá nh
Trên xâ u có đầy đủ cá c phép so sá nh:
==; !=; <; >; <=; >=
Cá c toá n tử so sá nh că n cứ theo thứ tự
từ điển
18
Hà m substr
Trả về mộ t xâ u con trong xâ u , bắ t đầ u từ ký tự thứ ,
lấy ký tự .
Nếu khô ng đủ ký tự tính từ vị trí , hà m chỉ lấy tớ i ký
tự cuố i cù ng trong xâ u
Độ phứ c tạ p tính toá n bằ ng số ký tự trong xâ u kết quả
19
0 1 2 3 4 5 6 7 8 9 10

a = O U T S T A N D I N G

b = a.substr(3, 5)

b =

20
0 1 2 3 4 5 6 7 8 9 10

a = O U T S T A N D I N G

b = a.substr(3, 100)

b =

21
Hà m insert

Chèn xâ u và o xâ u tạ i vị trí ()
Nếu , xâ u đượ c thêm và o cuố i xâ u

22
0 1 2 3 4 5 6

s = C O S T

N T E

s.insert(2, "NTE");

23
0 1 2 3 4 5 6 7 8 9

s = C O N T E S T

A N T

s.insert(7, "ANT");

24
Hà m erase
Xó a trong xâ u từ vị trí đi ký tự
Chỉ xó a đến hết xâ u dù từ vị trí khô ng cò n đủ ký tự .
Chú ý: Máy phả i cấ p phá t lạ i bộ nhớ và sao chép cá c
ký tự khô ng bị xó a sang vù ng nhớ mớ i (độ phứ c tạ p
tính toá n bằ ng độ dà i xâ u)
25
0 1 2 3 4 5 6 7 8 9

s = C O N T E S T A N T

s.erase(7, 100);

26
0 1 2 3 4 5 6

s = C O N T E S T

s.erase(2, 3);

27
Hà m replace

Thay loạ t ký tự trong xâ u tính từ vị trí đi


ký tự bở i xâ u
Nếu khô ng đủ ký tự tính từ vị trí , hà m
chỉ thay cá c ký tự cho đến hết xâ u
28
0 1 2 3 4 5 6 7

s = P R E C I S E

A C T I C

s.replace(2, 4, "ACTIC");

29
0 1 2 3 4 5 6 7 8 9 10

s = P R A C T I C E

O G R A M M I N G

s.replace(2, 100, "OGRAMMING");

30
Hà m find
Tìm vị trí xuấ t hiện đầ u tiên củ a xâ u trong xâ u tính từ vị trí , nếu khô ng
thấy trả về hằ ng string::npos (-1)
Nếu khô ng chỉ ra tham số , việc tìm kiếm tiến hà nh từ đầ u xâ u ()
s = "This is the first disk";
k = s.find("is"); //k = 2: This is the first disk
k = s.find("is", 3); //k = 5: This is the first disk
k = s.find("is", 8); //k = 19: This is the first disk
k = s.find("is", 20); //k = -1: This is the first disk
31
Hà m rfind
Tìm vị trí xuấ t hiện cuố i cù ng củ a xâ u trong xâ u tính từ vị trí trở về
trướ c, nếu khô ng thấy trả về hằ ng string::npos (-1)
Nếu khô ng chỉ ra tham số , việc tìm kiếm tiến hà nh từ cuố i xâ u ()
s = "This is the first disk";
k = s.rfind("is"); //k = 19: This is the first disk
k = s.rfind("is", 10); //k = 5: This is the first disk
k = s.rfind("is", 2); //k = 2: This is the first disk
k = s.rfind("is", 1); //k = -1: This is the first disk
32
Chuyển đổ i chữ hoa/thườ ng
Viết mộ t hà m lowercase(s) nhậ n và o mộ t xâ u và trả
về xâ u tạ o thà nh bằ ng cá ch chuyển tấ t cả cá c chữ cá i
hoa sang chữ thườ ng
Viết mộ t hà m uppercase(s) nhậ n và o mộ t xâ u và trả
về xâ u tạ o thà nh bằ ng cá ch chuyển tấ t cả cá c chữ cá i
thườ ng sang chữ hoa
33
const int delta = 'a' - 'A';

string lowercase(const string &s)


{
string t;
t.resize(s.length());
for (int i = 0; i < s.length(); i++)
if (s[i] >= 'A' && s[i] <= 'Z') t[i] =
s[i] + delta;
else t[i] = s[i];
return t;
}
34
const int delta = 'a' - 'A';

string uppercase(const string &s)


{
string t;
t.resize(s.length());
for (int i = 0; i < s.length(); i++)
if (s[i] >= 'a' && s[i] <= 'z') t[i] =
s[i] - delta;
else t[i] = s[i];
return t;
}
35
Chuyển đổ i giữ a số và xâ u
Muố n chuyển đổ i giữ a số và xâ u ký tự biểu diễn số đó , có nhiều cá ch và nhiều
hà m hỗ trợ

Mộ t cá ch đơn giả n nhấ t là tạ o mộ t luồ ng nhậ p xuấ t dạ ng stringstream


Cơ chế: Tậ n dụ ng cơ chế chuyển đổ i củ a bộ nhậ p xuấ t C++
Xuấ t ra luồ ng mộ t xâ u, đọ c từ luồ ng mộ t số ta chuyển đượ c xâ u thà nh số
Xuấ t ra luồ ng mộ t số , đọ c từ luồ ng mộ t xâ u, ta chuyển đượ c số thà nh xâ u. Chú ý là
khuô n dạ ng số cũ ng có thể định nghĩa như khuô n dạ ng củ a cout
36
Chuyển đổ i giữ a số và xâ u
Dù ng thư viện sstream
#include <sstream>
Khai bá o mộ t đố i tượ ng kiểu stringstream
stringstream cnv;
Chuyển đổ i
double r;
int i;
cnv << "12.34" << endl; //chú ý phải có dấu xuống dòng
cnv << "56" << endl; //chú ý phải có dấu xuống dòng
cnv >> r >> i; //r = 12.34; i = 56;
37
#include cnv << "123456789123456789" <<
<iostream> endl;
#include <string> cnv >> i;
#include <sstream> cout << "i = " << i << endl;
#include <iomanip> cnv << fixed << setprecision(18)
using namespace
<< 3.141592653589L << endl;
std;
cnv >> s;
cout << "Pi = " << s << endl;
int main()
{
cnv << std::hex << 123456789 <<
endl;
stringstream
cnv; cnv >> s;
long long i; cout << "123456789 = " << s <<
string s; endl;
}
38
Bà i tậ p
Từ trong xâ u: Mộ t dãy Input
chữ cá i liên tiếp cá ch The “art” of computer
nhau bở i mộ t hoặ c programming
nhiều ký tự khô ng phả i Output
chữ cá i The
Viết chương trình
art
Nhậ p và o mộ t xâ u
of
In ra cá c từ trong xâ u, computer
mỗ i từ mộ t dò ng programming
39
Dãy ngoặ c đú ng
Định nghĩa
Xâ u rỗ ng là dãy ngoặ c đú ng
Nhậ p và o mộ t xâ u cá c
Nếu là dãy ngoặ c đú ng thì () cũ ng là dấ u ngoặ c đó ng/mở
dãy ngoặ c đú ng
Nếu là hai dãy ngoặ c đú ng thì cũ ng là In ra ‘YES’ nếu xâ u đó
dãy ngoặ c đú ng
Ví dụ là dãy ngoặ c đú ng, in ra
(())(): đúng
‘NO’ nếu xâ u đó khô ng
(()))(: sai
((((((: sai phả i dãy ngoặ c đú ng
((())): đúng
40
do
Thuậ t toá n 1: Tìm cụ m
{
"()" nếu thấy thì xó a. int k = s.find("()");
Nếu xâ u khô ng cò n ký if (k < 0) break;
s.erase(k, 2);
tự nà o: YES
}
Nếu xâ u cò n lạ i ký tự : while (true);
NO if (s == "") cout <<
"YES";
else cout << "NO";
41
Ví dụ 1

( ( ( ) ) ( ) ( ) )

42
Ví dụ 1

( ( ) ( ) ( ) )

43
Ví dụ 1

( ( ) ( ) )

44
Ví dụ 1

( ( ) )

45
Ví dụ 1

( )

46
Ví dụ 2

( ( ( ) ) ) ) ( ( )

47
Ví dụ 2

( ( ) ) ) ( ( )

48
Ví dụ 2

( ) ) ( ( )

49
Ví dụ 2

) ( ( )

50
Thuậ t toá n 2: int depth = 0;
for (int i = 0; i < s.length();
Khở i tạ o biến depth = 0
i++)
Duyệt xâ u từ trá i qua phả i
{
Gặ p (: Tă ng depth lên 1
if (s[i] == '(') depth++;
Gặ p ): Giả m depth đi 1
else depth--; //s[i] = ')'
Nếu depth khô ng â m trong
if (depth < 0) break;
quá trình duyệt và kết thú c
}
bằ ng 0: Hợ p lệ
if (depth == 0)
Nếu depth â m trong quá
cout << "YES";
trình duyệt hoặ c kết thú c
else
khá c 0: Khô ng hợ p lệ
cout << "NO";
51
3
Ví dụ 1
2 2 2 2

1 1 1 1

0 0

( ( ( ) ) ( ) ( ) )

52
3
Ví dụ 2
2 2

1 1

0 0

-1

( ( ( ) ) ) ) ( ( )

53
Kiểu xâ u tổ ng quá t
Kiểu string là dẫ n xuấ t từ mộ t lớ p tổ ng quá t có tên là basic_string
Định nghĩa
typedef basic_string<char> string;
Chú ng ta dù ng kiểu string, thự c chấ t là basic_string<char>
 Có thể biểu diễn các loại xâu mà mỗi phần tử không phải là ký tự
basic_string<int>;
Lợi ích: Tận dụng được các phép toán insert, erase, replace, length
trên mảng số nguyên
54
Trá o bà i
Cho bộ bà i gồ m lá bà i đượ c xế p thà nh dãy thứ tự từ 1 tớ i , đầ u tiê n ngườ i
ta ghi và o mỗ i lá bà i mộ t số nguyê n là số thứ tự ban đầ u củ a lá bà i đó .
Phép trá o :
Lấy ra khỏ i bộ bà i lá bà i liên tiếp bắ t đầ u từ lá bà i thứ
Sau đó chèn lá bà i này và o trướ c lá bà i thứ trong số lá bà i cò n lạ i
.
Quy ướ c rằ ng nếu thì lá bà i lấy ra sẽ đượ c đưa và o cuố i dãy
Xá c định trạ ng thá i củ a bộ bà i sau phé p trá o
55
1 2 3 4 5 6 7 8 9

1 2 3 4 5 6 7 8 9

𝑆 ( 1,5,2 )
1 2 3 4 5 6 7 8 9

1 2 3 4 5 6 7 8 9
56
1 2 3 4 5 6 7 8 9

6 1 2 3 4 5 7 8 9

𝑆 ( 5 ,4,6 )
6 1 2 3 4 5 7 8 9

1 2 3 4 5 6 7 8 9
57
Đọ c thêm
Có rấ t nhiều hà m xử lý xâ u trong C++,
đọ c thêm trên internet để sử dụ ng đượ c
cà ng nhiều cà ng tố t
Xem thêm về kiểu xâ u cổ điển trong C
58

You might also like