Tải bản đầy đủ (.docx) (23 trang)

SKKN một số kinh nghiệm bồi dưỡng học sinh giỏi về kiểu dữ liệu xâu trong ngôn ngữ lập trình c++

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (157.09 KB, 23 trang )

SỞ GIÁO DỤC VÀ ĐÀO TẠO THANH HOÁ

TRƯỜNG
VĨNHTHANH
LỘC HOÁ
SỞ GIÁO
DỤC VÀTHPT
ĐÀO TẠO
TRƯỜNG THPT VĨNH LỘC

SÁNG KIẾN KINH NGHIỆM

SÁNG KIẾN KINH NGHIỆM

MỘT SỐ KINH NGHIỆM
BỒI DƯỠNG HỌC SINH GIỎI VỀ KIỂU DỮ LIỆU XÂU
TRONG NGƠN NGỮ LẬP TRÌNH C++
MỘT SỐ KINH NGHIỆM
BỒI DƯỠNG HỌC SINH GIỎI VỀ KIỂU DỮ LIỆU XÂU
TRONG NGƠN NGỮ LẬP TRÌNH C++
Người thực hiện: Bùi Thị Vân
Chức vụ: Giáo viên
Đơn vị công tác: Trường THPT Vĩnh Lộc
SKKN thuộc môn: Tin học

Người thực hiện: Bùi Thị Vân
Chức vụ: Giáo viên
Đơn vị công tác: Trường THPT Vĩnh Lộc
SKKN thuộc môn: Tin học



THANH HOÁ NĂM 2021


MỤC LỤC

1. Mở đầu
1.1. Lí do chọn đề tài
1.2. Mục đích nghiên cứu
1.3. Đối tượng nghiên cứu
1.4. Phương pháp nghiên cứu
2. Nội dung sáng kiến kinh nghiệm
2.1. Cơ sở lý luận của sáng kiến kinh nghiệm
2.2. Thực trạng vấn đề trước khi áp dụng sáng kiến kinh nghiệm
2.3. Các giải pháp đã sử dụng để giải quyết vấn đề
2.3.1. Kiểu xâu trong C++
2.3.2. Các dạng bài tập thường gặp
2.3.3. Một số bài tập áp dụng
2.4. Hiệu quả của sáng kiến kinh nghiệm đối với hoạt động giáo dục,
với bản thân, đồng nghiệp và nhà trường
3. Kết luận, kiến nghị
3.1. Kết luận
3.2. Kiến nghị

Trang
1
1
1
1
1
2

2
2
2
3
4
13
16
17
17
17



1. Mở đầu
1.1. Lý do chọn đề tài
Trong thời kỳ hội nhập, Công nghệ thông tin là một trong những ngành
mũi nhọn mang đến sự phát triển vượt bậc cho khoa học kỹ thuật. Chính vì vậy,
ngành cơng nghệ thơng tin đã trở thành một ngành học “hot” và thu hút rất nhiều
bạn học sinh sắp tốt nghiệp trung học phổ thơng, đặc biệt là những bạn u thích
máy tính và đam mê công nghệ. Tuy nhiên một thực tế tại các trường trung học
phổ thơng thì mơn Tin học đang được đa số các học sinh xem là “môn phụ” và
dành rất ít sự quan tâm cho mơn học này. Vì vậy để góp phần khẳng định vai trị
của môn Tin học trong trường so với các môn học khác và tạo điểm nhấn kích
thích sự quan tâm, hứng thú của học sinh với mơn Tin thì việc nâng cao chất
lượng đội tuyển học sinh giỏi là một nhiệm vụ trọng tâm.
Trên thực tế, ngoại trừ các trường chuyên thì ở các trường trung học phổ
thơng khác ngơn ngữ đang được sử dụng chủ yếu để dạy cho đội tuyển học sinh
giỏi tin học là ngôn ngữ Pascal. Tuy nhiên hiện nay trong các kỳ thi học sinh
giỏi Tỉnh thì ngơn ngữ C++ là ngơn ngữ đang được sử dụng thay thế dần ngơn
ngữ lập trình Pascal. Vì vậy để các em học sinh trong đội tuyển học sinh giỏi Tin

học của nhà trường tiếp cận ngôn ngữ lập trình C++ là một vấn đề rất cấp thiết.
Đây cũng là một thuận lợi cho các em có định hướng học ngành cơng nghệ
thơng tin ở bậc đại học vì vậy sẽ dễ tạo hứng thú học tập cho các em hơn.
Qua hai năm bồi dưỡng học sinh giỏi cấp tỉnh bằng việc cho học sinh sử
dụng ngôn ngữ lập trình C++, tơi nhận thấy dữ liệu kiểu xâu thường gặp phổ
biến trong các bài toán và việc vận dụng linh hoạt các thao tác xử lí kiểu dữ liệu
này vào giải quyết các bài tốn liên quan khơng phải dễ. Bên cạnh đó tài liệu
tham khảo phổ thơng chính thống về ngơn ngữ lập trình C++ cịn khá hạn chế.
Vì vậy, với mong muốn phần nào giúp học sinh cũng như giáo viên trong việc
tìm ra lời giải cho một số bài toán liên quan tới kiểu dữ liệu xâu dễ dàng hơn, tôi
chọn đề tài “MỘT SỐ KINH NGHIỆM BỒI DƯỠNG HỌC SINH GIỎI VỀ
KIỂU DỮ LIỆU XÂU TRONG NGƠN NGỮ LẬP TRÌNH C++” làm đề tài
sáng kiến kinh nghiệm của mình.
1.2. Mục đích nghiên cứu
- Giới thiệu một số thao tác xử lí xâu cơ bản trong c++.
- Hệ thống một số dạng bài tập thường gặp giúp học sinh và giáo viên phần
nào nhận dạng được một số bài tập liên quan.
1.3. Đối tượng nghiên cứu
- Các bài toán liên quan đến kiểu dữ kiệu xâu.
1.4. Phương pháp nghiên cứu
- Khảo sát, phân tích, giải quyết vấn đề kết hợp giữa lí thuyết và thực hành.
- Kết hợp thực tiễn dạy đội tuyển học sinh giỏi ở trường trung học phổ thông
Vĩnh Lộc.
- Tham khảo các tài liệu về ngơn ngữ lập trình C++ và tài liệu về sáng kiến.
- Tham khảo ý kiến góp ý của đồng nghiệp.

1


2. Nội dung sáng kiến kinh nghiệm

2.1. Cơ sở lí luận của sáng kiến kinh nghiệm
Trong điều kiện hướng tới thực hiện chương trình GDPT mới (2018),
trước tình hình thực tế Bộ giáo dục và đào tạo đã ban hành công văn
3280/BGDDT-GDTrH, kèm theo hướng dẫn điều chỉnh nội dung dạy học cấp
trung học phổ thông năm 2020. Đối với việc giảng dạy nội dung về ngơn ngữ
lập trình của mơn Tin học lớp 11, Bộ có một số lưu ý cụ thể là “Hiện nay có
nhiều ngơn ngữ lập trình có tính cập nhật, hiện đại, đồng thời thơng dụng trong
giáo dục phổ thông ở nhiều nước mà các trường có thể lựa chọn như Python, C,
C++,... “.
Trong ngơn ngữ lập trình C++, kiểu dữ liệu xâu thường có hai loại với
thao tác được sử dụng với hai loại này là khác nhau. Vấn đề quan trọng là tùy
thuộc vào yêu cầu của mỗi bài toán cụ thể, làm thế nào để học sinh phân loại
được dạng toán và sử dụng kiểu dữ liệu phù hợp, thuận lợi cho quá trình lập
trình.
2.2. Thực trạng vấn đề trước khi áp dụng sáng kiến kinh nghiệm
Qua thực tế dạy bồi dưỡng đội tuyển học sinh giỏi, tôi nhận thấy trong đề
thi học sinh giỏi tỉnh qua các năm ở các địa phương hầu hết đều có bài tốn liên
quan đến kiểu dữ liệu xâu. Bên cạnh đó khi bắt tay vào giải quyết bài tốn học
sinh thường gặp khó khăn khi sử dụng các thao tác cơ bản với kiểu dữ liệu này
và cũng khá nhiều lần nhầm lẫn giữa thao tác của kiểu xâu theo phong cách C và
kiểu xâu theo phong cách C++.
2.3. Các giải pháp đã sử dụng để giải quyết vấn đề
2.3.1. Kiểu xâu trong C++
Trong C++ có hai loại xâu, xâu theo phong cách của C (C – style string)
và xâu theo phong cách của C++ (C++ - style string).
C - Style string thực sự là một mảng các ký tự, nhưng có một số hàm khác
nhau được sử dụng cho các xâu, ví dụ như thêm vào các xâu, tìm chiều dài của
xâu, và các hàm kiểm tra phù hợp của string với một biểu thức chính quy
(regular expression).
C++ - Style string thực chất là một mảng các ký tự, nhưng sử dụng dấu

nháy kép để dánh dấu một xâu kí tự (string literals).
2.3.1.1. C – style string
2.3.1.1.1. Khai báo
char st[] = { 'h', 'e', 'l', 'l', ' ', 'o', ' ' ,'w', 'o', 'r', 'd', '\0'};
hoặc
char st[] = "Hello word'';
hoặc
char st[100];
2.3.1.1.2. Một số hàm thơng dụng
Tên hàm
Mơ tả
size_t strlen(const char *str)

Tính tốn độ dài của xâu, khơng tính ký tự kết
thúc (ký tự null)
2


char *strcpy(char
const char *src)

*dest, Sao chép xâu 'src' sang cho 'dest'.

int strcmp(const char *str1, So sánh hai string cho bởi tham số con trỏ
const char *str2)
str1, và str2. Nó trả về một số nguyên > 0
nghĩa là str1 > str2. Và = 0 nghĩa là 2 xâu
giống nhau, ngược lại str1 < str2.
char *strcat(char *st1, const Nối xâu st2 vào cuối xâu st1
char *st2)

char *strchr(const char *str, Vị trí xuất hiện đầu tiên của xâu str trong xâu
int c)
strchr bắt đầu từ vị trí c.
int atoi(const char * str);

Chuyển đổi xâu thành số nguyên

Itoa(int n, char *st, cơ số)
Chuyển đổi số nguyên thành xâu
2.3.1.2. C++ - style string
2.3.1.2.1. Khai báo
String st; // khai báo xâu st
2.3.1.2.2. Khởi tạo hoặc gán giá trị
Có thể khởi tạo hoặc gán giá trị cho biến string theo nhiều cách:
string st("");
// Khởi tạo xâu st rỗng
string st1("Hello");
// Khởi tạo xâu "Hello" cho st1
string st2 = "hello word"; // Khởi tạo xâu "Hello A1" cho st2
string st= "88";
// Khởi tạo xâu "88" cho st, không phải số
2.3.1.2.3. Xuất một xâu kí tự
cout<2.3.1.2.4. Nhập một xâu kí tự
cin>>st1;
Trong trường hợp đọc tệp có cả dữ liệu kiểu số và kiểu xâu :
Int n; String st1;
Cin>>n;
Cin.ignore(32767,’\n’); // Xóa khỏi bộ nhớ đệm 32767 kí tự hoặc đến
khi gặp kí tự ‘\n’ xuống dịng

Getline(cin,st1);
Nhập một văn bản bao gồm kí tự xuống dịng
string st;
getline(cin, st, '_'); // Nhập văn bản nhiều dịng cho đến khi gặp kí tự
dấu gạch dưới ‘_’.
2.3.1.2.5. Một số thao tác cơ bản
Tên hàm
Mô tả
st.length()

Độ dài của xâu st

st=st1+st2;

Nối xâu st2 vào cuối xâu st1
3


st.at(vt);

Lấy kí tự ở vị trí vt của xâu st

st1<tốn tử so sánh>st2

So sánh hai xâu st1 và st2

St.find(s)

Trả về vị trí đầu tiên khi tìm thấy xâu s trong xâu
st


St.find(s,x)

Trả về vị trí đầu tiên khi tìm thấy xâu s trong xâu
st bắt đầu từ vị trí x

st.erase(x, y);

Xóa đi y kí tự trong xâu st bắt đầu từ vị trí x

st.substr(x,y)

Trả về xâu con từ vị trí thứ x đến y trong xâu st

2.3.2. Các dạng bài tập thường gặp
2.3.2.1. Xử lí số nguyên lớn
Phương pháp chung: Để thực hiện các phép tính hoặc xử lý với số
nguyên ngoài phạm vi biểu diễn được cung cấp, cách đơn giản nhất là sử dụng
xâu kí tự để biểu diễn với mỗi ký tự của xâu tương ứng với một chữ số của số
nguyên lớn tính từ trái qua phải.
Bài 1: Cộng hai số nguyên lớn
Cho hai số nguyên dương lớn có có độ dài khơng q 200 chữ số. Hãy đưa
ra tổng của 2 số nguyên đó.
 Ý tưởng:
Sử dụng xâu để lưu 2 số lớn.
Bước 1: Chuẩn hóa hai xâu để có độ dài bằng nhau. Nếu xâu nào ngắn
hơn thì thêm các kí tự ‘0’ vào đầu xâu đó.
Bước 2: Duyệt lần lượt từ cuối hai xâu về đầu:
- Tách từng phần tử của hai xâu chuyển sang kiểu số.
- Tính tổng:

Tổng= số 1 + số 2 + nhớ ( ban đầu nhớ =0)
Nhớ=tổng/10
Tong =tong % 10;
- Chuyển đổi tổng tính được sang dạng sơ rồi cộng vào xâu kết quả.
- Lưu ý cộng thêm giá trị nhớ lần cuối nếu gia trị nhớ khác 0.
 Đoạn chương trình tính tổng hai số ngun lớn
String congxau(string a, string b)
{
String c;
Long n1=a.length(), long n2=b.length(), i, nho=0, tong;
If (n1>n2) b.insert(0,n1-n2,’0’);
If (n1c=a;
for (i=a.length()-1;i>0;i--)
{
tong=(a[i]-48)+(b[i]-48)+nho;
4


nho=tong/10;
tong=tong%10;
c[i]=char(tong+48);}
If (nho>0) c=char(nho+48)+c;
Return c;
}
Bài 2: Nhân một số nguyên lớn với một số nguyên nhỏ
 Ý tưởng
- Duyệt từ cuối xâu lớn về đầu xâu.
- - Tách từng phần tử của xâu chuyển sang kiểu số và tính tích.
Tich=số nhỏ*tg-nhớ (tg là số được tách từ xâu lớn)

Nhớ=tich/10;
Tich=tich%10
- Chuyển đổi giá trị tích tính được sang kí tự rồi gán cho xâu kết quả.
- Lưu ý cộng thêm giá trị nhớ lần cuối nếu nhớ khác ‘0’.
 Đoạn chương trình tham khảo
String nhan1so(string a, int k)
{
String b;
Long i,nho=0, tich;
For (i=a.length();i>=0,i--)
{
tich=nho+(a[i]-48)*k;
nho=tich/10;
tich=tich%10;
b=b+char(tich+48);
}
If (nho !=0) b=char(nho+48)+b;
While (b.length()>1 && b[0]==’0’)
b.erase(0,1);
Return b;
}
Bài 3: Nhân hai số nguyên lớn
Cho hai số nguyên dương lớn a, b có có độ dài khơng q 200 chữ số. Hãy
đưa ra tích của 2 số ngun đó.
 Ý tưởng:
- Duyệt từ cuối xâu s về đầu xâu.
- Tách từng phần tử của xâu a nhân với xâu b.
- Cộng liên tiếp các kết quả thu được (lưu ý trước khi cộng 2 xâu thêm
kí tự ‘0’ vào cuối xâu thứ hai)
- Xử lí các kí tự ’0’ trước xâu sau khi cộng.

2.3.2.2. Biến đổi xâu
5


Phương pháp chung: Đây là dạng cơ bản thường gặp, việc biến đổi xâu
được thực hiện trên mỗi ký tự trong xâu nên cần nắm rõ các thao tác trên kiểu
dữ liệu xâu để vận dụng một cách linh hoạt vào từng bài tập cụ thể.
Bài 1: Tìm số lớn
Cho một dãy gồm N các kí tự có mặt trên bàn phím trong đó có ít nhất 4
chữ số (N<106).
u cầu: Hãy loại bỏ một số kí tự cuối dãy sao cho 4 kí tự cuối cùng cịn lại
theo đúng thứ tự đó tạo nên số lớn hất.
Dữ liệu vào: file văn bản BAI2.INP chứa N kí tự.ư
Kết quả ra: file văn bản BAI2.OUT chứa 4 chữ số tạo thành số lớn nhất.
Ví dụ:
BAI1.INP
BAI1.OUT
2124t5j4r05f704y652k393

7693

 Ý tưởng:
- Xóa các kí tự khơng phải là kí tự chữ số xuất hiện trong xâu.
- Thực hiện tìm lần lượt các chữ số lớn nhất ở 4 vị trí từ trái qua phải.
Ví dụ chữ số lớn nhất mà kí tự chữ số lớn nhất từ đầu xâu đến vị trí
s.length()-4,...
 Chương trình tham khảo
#include <bits/stdc++.h>
using namespace std;
int main()

{
short i,k,csmax;
string s,s1="";char max[1];
ifstream x("BAI1.INP");
ofstream y("BAI1.OUT");
x>>s;
for (int i=0; iif (s[i]!='0' && s[i]!='1' && s[i]!='2' && s[i]!='3' &&
s[i]!='4' && s[i]!='5' && s[i]!='6' && s[i]!='7' && s[i]!='8' &&
s[i]!='9')
{
s.erase(i,1);
i--;
}
y<for (k=4;k>=1;k--)
{if (s.length()==k)
{s1=s1+s; break;}
max[0]=s[0];int n=s.length();
for (i=1;i<=n-k;i++)
6


if (s[i]>max[0])
{max[0]=s[i];
csmax=i;}
s1=s1+s[csmax];
s.erase(0,csmax+1);
}
y<

x.close(); y.close();
return 0;}
Bài 2: TỪ VỰNG [1]
Muốn cải thiện vốn từ vựng tiếng Anh của mình thơng qua trị chơi nhận
diện từ, Quyên tự viết ra một xâu S độ dài khơng q 106 chỉ gồm các kí tự
thường trong bảng chữ cái tiếng Anh. Từ đó, Qun tìm ra tất cả từ vựng có
trong S. Một từ vựng sẽ thu được bằng cách ghép một số kí tự liên tiếp lấy từ S,
giữ nguyên trật tự của chúng, thỏa mãn một trong hai điều kiện sau:
 Bắt đầu bằng một nguyên âm (là các chữ cái: a, e, i, o, u) và kết thúc bằng
một phụ âm (là các chữ cái còn lại).
 Bắt đầu bằng một phụ âm và kết thúc bằng một nguyên âm.
Yêu cầu: Hãy giúp bạn Quyên đếm số lượng từ vựng có trong S theo quy tắc
trên.
Dữ liệu: Vào từ tệp CAU4.INP gồm xâu S khơng q 106 kí tự.
Kết quả: Ghi ra tệp CAU4.OUT một số ngun là kết quả tìm được.
Ví dụ:
CAU4.INP
CAU4.OUT
Ràng buộc:
adceba
9
- Có ⅓ số
test có độ dài
4
xâu S khơng q 10 .
- Có ⅔ số test cịn lại khơng có rằng buộc gì thêm.
 Ý tưởng
- Duyệt lần lượt từng kí tự trong xâu, lưu số lượng kí tự nguyên âm và phụ
âm đến thời điểm hiện tại đang xét.
- Nếu kí tự đang xét là một nguyên âm thì số lượng từ vựng bằng số lượng

từ vựng trước đó cộng vơi số lượng phụ âm, đồng thời tăng số lượng
nguyên âm lên 1 đơn vị.
- Nếu kí tự đang xét là một phụ âm thì số lượng từ vựng bằng số lượng từ
vựng trước đó cộng vơi số lượng nguyên âm, đồng thời tăng số lượng phụ
âm lên 1 đơn vị.
 Chương trình tham khảo
#include<bits/stdc++.h>
using namespace std;
int n;
long long res=0;
string s;
bool nguyen_am(char ch){
7


return (ch=='a'||ch=='e'||ch=='i'||ch=='o' ||ch=='u');
}
const char* ff = "CAU4.INP";
const char* fo = "CAU4.OUT";
int main(){
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
freopen(ff,"r",stdin);
freopen(fo,"w",stdout);
cin>>s;
n=s.length();
long long pa=0, na=0;
for (int i=0;i{
if (nguyen_am(s[i])) {

res+=pa;na++;
}
else{
res+=na; pa++;
}
}
cout<return 0;
}
2.3.2.3. Tìm xâu con
Phương pháp chung: Để tìm các xâu con của xâu ban đều thỏa mãn một
điểu kiện cho trước thì thường sử dụng phương pháp vét cạn với bộ dữ liệu đầu
vào nhỏ, tuy nhiên nên sử dụng linh hoạt các phương pháp khác như phương
pháp quy hoạch động trong trường hợp bài tốn có bộ dữ liệu lớn.
Bài 1: Đếm xâu con [2]
Cho xâu S bao gồm các chữ cái ‘A’ .. ‘Z’ và các chữ số ‘0’ … ‘9’.
Yêu cầu: Đếm số lượng xâu con trong xâu S có số lượng chữ cái nhiều hơn số
lượng chữ số (Xâu con của xâu S là một dãy các kí tự liên tiếp trong xâu S).
Dữ liệu vào: Đọc từ tệp BAI1.INP gồm xâu S có độ dài <=104.
Kết quả ra: Ghi ra tệp BAI1.OUT kết quả tìm được.
Ví dụ:
BAI1.INP
BAI1.OUT
AC54C
6
 Ý tưởng:
- Gọi a[i] là số lượng kí tự chữ cái in hoa từ kí tự đầu tiên đến kí tự thứ i
trong xâu S.
8



- Gọi b[i] là số lượng chữ số tính từ kí tự đầu tiên đến kí tự thứ i trong xâu
S.
- Khi đó đoạn từ kí tự thứ i đến kí tự thứ j trong xâu S có số lượng chữ cái
nhiều hơn số lượng chữ số nếu a[j]-a[i]>b[j]-b[i].
- Sử dụng phương pháp vét cạn để tính số xâu con thõa mãn điều kiện đề
bài.
 Chương trình tham khảo
#include<bits/stdc++.h>
using namespace std;
string s;
int dem=0;long a[10001],b[10001];
const char* ff = "BAI1.INP";
const char* fo = "BAI1.OUT";
int main(){
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
freopen(ff,"r",stdin);
freopen(fo,"w",stdout);
cin>>s;
if (s[0]>=65 && s[0]<=90) a[0]=1;
else a[0]=0;
for (int i=1;iif (s[i]>=65 && s[i]<=90) a[i]=a[i-1]+1;
else a[i]=a[i-1];
if (s[0]>=48 && s[0]<=57) b[0]=1;
else b[0]=0;
for (int i=1;iif (s[i]>=48 && s[i]<=57) b[i]=b[i-1]+1;
else b[i]=b[i-1];

for (i=0;ifor (j=I;jif (a[j]-a[i]>b[j]-b[i]) dem++;
cout<return 0;}
Bài 2. Gửi thư
Vị Giám đốc công ty XYZ cần gửi một văn bản quan trọng tới một đối tác
của mình. Văn bản là một xâu S các chữ cái la tinh in thường. Để bảo mật nội
dung văn bản, ông Giám đốc gửi 2 bức thư. Bức thư thứ nhất là phần đầu S1 của
xâu S, bức thư thứ 2 là phần cuối S2 của S. Hai bức thư S1 và S2 đảm bảo đầy
đủ nội dung của S, tuy nhiên có thể một phần cuối của S1 có thể được viết lặp
lại trong phần đầu của S2, song số kí tự được viết lặp lại khơng biết trước.
Yêu cầu: Cho hai xâu Sb và Se, hãy xác định một xâu S có thể là nội dung của
bức thư sao cho độ dài của xâu S là ngắn nhất.
Dữ liệu vào: BAI2.INP
9


Dòng đầu chứa xâu S1, dòng thứ hai chứa xâu S2. Mỗi xâu có độ dài <= 250.
Kết quả: BAI2.OUT Ghi ra độ dài của xâu S tìm được.
Ví dụ:
BAI2.INP
BAI2.OUT
Truong trung học phổ thông
Truong trung học phổ thông
trung học phổ thơng Vinh Loc
Vinh Loc
 Ý tưởng:
- Tìm xâu con chung dài nhất của hai xâu tương ứng tính từ cuối xâu s1
và đầu xâu s2 (giả sử độ dài xâu con chung là max).

- Kết quả bài toán là s1.length() + s2.length()-max
 Chương trình
#include<bits/stdc++.h>
using namespace std;
string s1,s2; int k=1;
const char* ff = "BAI3.INP";
const char* fo = "BAI3.OUT";
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
freopen(ff,"r",stdin);
freopen(fo,"w",stdout);
cin.getline(s1,100); cin.getline(s2,100);
while (s1.substr(s1.length()-k-1,s1.length()-1) ==s2.substr(0,k))
{k++;}
Cout<return 0;}
2.3.2.4. Xâu đối xứng (Palindrome)
Phương pháp chung: Xâu Palindrome hay cịn gọi là xâu đối xứng, có
nghĩa một xâu khi đọc các ký tự trong xâu từ trái sang phải cũng giống từ phải
sang trái.
Với những bài tập kiểm tra xâu Palindrome hay tìm kiếm xâu có tính chất
Palindrome thì trước hết nên xây dựng hàm kiểm tra tính chất đối xứng của một
xâu với độ phức tạp O(n), trên cơ sở đó chúng ta đi giải quyết những bài tập khó
hơn.
Bài 1. Xâu Palindrome
Cho một xâu S có độ dài không vượt quá 10 6. Kiểm tra xem xâu S có phải
là xâu Palindrome hay khơng?
 Ý tưởng:
Một xâu s có tính chất đối xứng khi s[i] = s[n-i+1] với i chạy từ 1 đến

length(s) div 2. Dựa trên cơ sở đó ta xây dựng hàm kiểm tra.

 Chương trình tham khảo:
#include <bits/stdc++.h>
using namespace std;
10


String s;
Bool kt(string st);
{
Kt=true;
Int i=0;
While ( i<=st.length()/2 && st[i] != st[st.length()-1-i]) i++;
If (i>st.length()/2) kt=true; else kt=false;
Return kt;
}
int main(){
ios_base::sync_with_stdio;
cin.tie(0);
cout.tie(0);
freopen("BAI1.INP","r",stdin);
freopen("BAI1.OUT","w",stdout)
;
cin>>s;
if kt(s) cout<<”Xau doi xung”
else cout “Xau khong doi xung”;
return 0;
Bài 2. (5 điểm) Từ đối xứng
Bờm là một học sinh rất chuyên cần, hôm nay Bờm đi học sớm, đi đến

lớp thấy 2 bạn đang chơi trị chơi tìm từ đối xứng. Nội dung trị chơi là: có một
trang văn bản, hai bạn sẽ tìm số lượng từ đối xứng nhiều nhất. Bờm nghĩ việc
tìm như hai bạn thì lâu quá nên mình sẽ lập trình để tìm ra đáp số.
Từ được phân biệt nhau bởi dấu cách (cịn gọi là kí tự cách trống – space).
Hai từ được gọi là đối xứng nếu từ đó đọc từ bên trái sang cũng giống như
khi đọc từ bên phải sang.
Ví dụ: ‘tom’ và ‘mot’ là hai từ đối xứng.
Cho tệp văn bản DOIXUNG.INP là một xâu kí tự khơng q 10 5 kí tự bao
gồm các kí tự từ ‘a’ đến ‘z’ và các kí tự cách trống.
In ra tệp DOIXUNG.OUT là số từ đối xứng tương ứng có trong tệp
DOIXUNG.INP.
Ví dụ:
DOIXUNG.INP
DOIXUNG.OU Giải thích
T
aba aba
0
2 từ aba và aba ko được
gọi là từ đối xứng
ab ab cd ba cd ba dc dc 2
ab - ba
cd - dc
tom la mot loai dong 1
tom - mot
vat
 Ý tưởng:
- Tách lần lượt các từ trong xâu lưu vào một mảng.
11



- Khi nạp một từ vào mảng:
+ Kiểm tra xem nó có là từ đối xứng của từ nào đã nạp vào mảng trước
đó hay khơng, nếu thõa mãn thì tăng biến đếm lên một đơn vị đồng thời
đánh dấu từ đã được xét để không xét lại.
+ Tiếp tục xét các từ tiếp theo cho đến hết các từ trong xâu ban đầu.
 Chương trình tham khảo
#include <bits/stdc++.h>
using namespace std;
ifstream f("doixung.inp");
ofstream g("doixung.out");
long i,d=0,j;
string x,s1,s[100000];
bool vt[100000];
string dao(string s1)
{
string s3="";
for (int j=0;js3=s1[j]+s3;
return s3;
}
int main()
{ getline(f,x);
i=0;
x=x+' ';
s1="";
int n=0;
cout<memset(vt,0,sizeof(vt));
while (x.length()>i)
{

if (x[i]!=' ')
{
s1=s1+x[i];
}
if (x[i]==' ')
{
string s2=s1;
s1=dao(s1);
bool kt=true;
for (int i=1;i<=n;i++)
{
if (s2==s[i] && s2.size()==s[i].size()) continue;
if (s1==s[i] && s1.size()==s[i].size() && s[i].size()>0)
{
12


if (vt[i]==0)
{
kt=false;
vt[i]=1;
} else break;
}
}
s1=dao(s1);
if (!kt) d++;
n++;
s[n]=s1;
s1="";
if (!kt) vt[n]=1;

}
i++;
}
g<return 0;
}
2.3.3. Một số bài toán áp dụng
Bài 1. Sắp xếp xâu
Mỗi xâu kí tự St được lấy từ tập các ký tự ’a’...’z’, ’0’...’9’ và có độ dài
tối đa là 1000 kí tự. Cho N xâu kí tự St (0 < N ≤ 200).
Yêu cầu: Thực hiện sắp xếp N xâu kí tự St theo thứ thự không giảm của số
lượng các kí tự chữ số có trong mỗi xâu St. Nếu hai xâu có cùng số lượng chữ số
thì đưa xâu lớn hơn trước.
Dữ liệu vào: Cho trong file văn bản SAPXEP.INP có cấu trúc như sau:
- Dịng 1: Ghi số nguyên N.
- N dòng tiếp theo: Mỗi dòng ghi một xâu St.
Dữ liệu ra: Ghi ra file văn bản SAPXEP.OUT theo cấu trúc như sau:
- Ghi N dòng: Mỗi dòng ghi một xâu St, các xâu được ghi theo thứ tự đã sắp
xếp.
Ví dụ:
SAPXEP.INP SAPXEP.OUT
3
cb1
abc1x2y3z
1cd7hd
cb1
abc1x2y3z
1cd7hd
 Ý tưởng:
- Xây dựng hàm đếm số lượng các kí tự là chữ số trong một xâu.

- Xây dựng hàm sắp xếp xâu theo thứ tự không giảm số lượng chữ số trong
các xâu, khi sắp xếp chú ý trường hợp hai xâu có số lượng kí tự chữ số
bằng nhau thì xâu nào lớn hơn được sắp xếp trước.
Bài 2: Xâu Palindrome
13


Một xâu gọi là đối xứng nếu xâu đó đọc từ trái sang phải cũng
giống như đọc từ phải sang trái. Cho một xâu S hãy tìm số kí tự ít nhất cần thêm
vào xâu S để S trở thành xâu đối xứng.
Dữ liệu vào: BAI2.INP gồm
Gồm một dòng là xâu S có độ dài <104
Dữ liệu ra: Ghi vào tệp BAI2.OUT
- Dịng 1: Đưa ra số lượng kí tự ít nhất cần chèn thêm vào
- Dòng 2: Các kí tự cần chèn
Ví dụ:
BAI2.INP
BAI2.OUT
EDBABCD
2
EC
 Ý tưởng:
- Gọi S2 là xâu đảo của xâu S1 ban đầu, T là xâu con chung dài nhất của
S1 và S2. Khi đó các kí tự của S1 khơng thuộc T chính là các kí tự cần chèn vào
S1 để S1 trở thành xâu đối xứng
- Bài tốn trở thành tìm dãy con chung dài nhất của hai dãy tương ứng là
2 xâu S1 và S2 bằng phương pháp quy hoạch động.
Sử dụng mảng L[0..max][0..max] để lưu độ dài dãy con chung dài nhất
với L[i][j] là độ dài dãy con chung dài nhất của hai dãy xâu s1 và s2:
Khi đó:

L[0][j] = 0 với i=1..N (N = s1.length())
L[i][0] = 0 với j=1..M (M = s2.length())
Với :i=1..N; j=1..M
Nếu s1[i] = s2[j] thì
L[i][j]:= L[i-1][j-1] + 1
ngược lại thì L[i][j] = max{L[i-1][j], L[i][j-1]}
Bài 4: Xâu con
Cho trước hai xâu kí tự S1 và S2. Viết chương trình tính số lần lặp lại của
xâu S1 trong xâu S2.
Dữ liệu vào: từ tệp văn bản BAI3.INP gồm:
- Dòng đầu tiên chứa xâu S1.
- Dòng thứ 2 chứa xâu S2.
Kết quả: ghi ra tệp văn bản BAI3.OUT chỉ duy nhất một số là số lần lặp lại của
xâu S1 trong xâu S2.
Ví dụ:
BAI3.INP
BAI3.OUT
aba
4
babababab
a

 Ý tưởng:
- Khởi tạo biến đếm d=0;
14


- Tìm vị trí xuất hiện đầu tiên của xâu con trong xâu S2, nếu còn xuất hiện
xâu S1 trong xâu S2 thì tăng biến đếm lên 1 đơn vị, sau đó xóa đi các kí
tự từ đầu xâu S2 đến kí tự ở vị trí xuất hiện đầu tiên.

- Tiếp tục thực hiện bước trên cho đến khi ko còn xuất hiện xâu S1 trong
xâu S2.
Bài 5: Đoạn max
Cho chuỗi ký tự S gồm các chữ cái in hoa (A…Z) với độ dài khơng vượt q
104.
u cầu: Hãy tìm đoạn con các kí tự liên tiếp dài nhất sao cho khơng có kí tự
nào xuất hiện nhiều hơn một lần. Trong trường hợp có nhiều hơn một đoạn con
có cùng chiều dài dài nhất, hãy chỉ ra đoạn xuất hiện đầu tiên trong chuỗi S.
Dữ liệu: Vào từ văn bản DOANMAX.INP:
- Gồm một dòng duy nhất chứa chuỗi S.
Kết quả: Ghi ra file văn bản DOANMAX.OUT
- Chỉ một dòng duy nhất chứa số nguyên P và L tương ứng là vị trí và chiều
dài của đoạn con dài nhất tìm được.
Ví dụ:
DOANMAX.INP
DOANMAX.OUT
ABABCDAC
34
Lưu ý: Có 80% test có độ dài xâu khơng vượt q 255.
Giải thích test ví dụ: Đoạn con dài nhất tìm được là ABCD có vị trí 3 và độ dài 4.
 Ý tưởng:
Lần lượt tìm từ đầu xâu các đoạn con liên tiếp các kí tự trong xâu S thõa
mãn điều kiện đề bài, so sánh độ dài xâu hiện tại tìm được với xâu dài nhất đã
đánh dấu trước đó. Thực hiện đến khi kết thúc xâu ban đầu.
Bài 5: Palindrome (5 Điểm)
Palindrome là xâu ký tự mà nếu đọc nó từ trái sang phải cũng như từ phải
sang trái ta được cùng một xâu. Một xâu ký tự bất kỳ ln có thể biểu diễn như
là một dãy các palindrome nếu như ta coi xâu chỉ gồm một ký tự ln là một
palindrome.
Ví dụ: Xâu ‘bobseesanna’ có thể biểu diễn dưới dạng dãy các palindrome theo

nhiều cách, chẳng hạn:
‘bobseesanna’ = ‘bob’ + ‘sees’ + ‘anna’
‘bobseesanna’ = ‘bob’ + ‘s’ + ‘ee’ + ’s’ + ‘anna’
‘bobseesanna’ = ‘b’ +’o’ + ‘b’ + ‘sees’ + ‘a’ + ‘n’ + ‘n’ + ‘a’
Yêu cầu: Cho xâu ký tự s, cần tìm cách biểu diễn xâu s dưới dạng một dãy gồm
số ít nhất các palindrome.
Ví dụ: Cho s=‘bobseesanna’, do ta có ‘bobseesanna’ = ‘bob’ + ‘sees’ + ‘anna’
và khơng thể biểu diễn ‘bobseesanna’ bởi ít hơn là 3 palindrome nên biểu diễn
này chính là biểu diễn cần tìm.
Dữ liệu vào: Vào từ tập tin văn bản PALINDR.INP, gồm một dịng chứa xâu
ký tự s gồm khơng q 255 ký tự.
15


Kết quả: Đưa ra tập tin văn bản PALINDR.OUT:
Dòng đầu tiên ghi k là số lượng ít nhất các palindrome trong biểu diễn tìm được;
Dịng thứ i trong số k dòng tiếp theo ghi palindrome p i (i=1, 2, ..., k) sao cho s =
p1p2...pk.
PALINDR.INP
bobseesanna

PALINDR.OUT
3
bob
sees
anna

PALINDR.INP
aabbaaaabb


PALINDR.OUT
2
aa
bbaaaabb

 Ý tưởng:
Li là độ dài lớn nhất của palindrome độ dài lẻ nhận Si làm tâm
Ci là độ dài lớn nhất của palindrome độ dài chẵn nhận Si và Si+1 làm tâm.
Ta xét từng vị trí i:
Xem Si có phải là tâm của Palindrome có lẻ kí tự khơng? (ví dụ Palindrome
MADAM có tâm là kí tự D)
Xem Si và Si+1 có phải là tâm của Palindrome có chẵn kí tự khơng? (ví dụ
Palindrome ABBA có tâm là 2 kí tự BB)
Với mỗi kí tự ta tìm palindrome dài nhất nhận nó là tâm, cập nhập lại kết
quả khi duyệt. Ta duyệt từ giữa ra để dùng kết quả hiện tại làm cận.
Bài 6. Siêu đối xứng
Một xâu có độ dài lớn hơn 1 chỉ gồm các chữ cái la tinh in thường được
gọi là đối xứng, nếu ta đọc xâu đó từ trái sang phải và từ phải sang trái là như
nhau. Một xâu được gọi là siêu đối xứng, nếu nó là xâu đối xứng hoặc được tạo
thành bằng cách ghép liên tiếp từ nhiều xâu đối xứng.
Yêu cầu: Cho một xâu S, hãy đếm số xâu con siêu đối xứng của S. ( Xâu con
của một xâu S là một đoạn liên tiếp các ký tự của S)
Dữ liệu: file văn bản BAI6.INP Chứa xâu S với độ dài không vượt quá 1000.
Kết quả: Ghi ra file văn bản BAI6.OUT số xâu con tìm được.
Ví dụ:
BAI6.INP
BAI6.OUT
BAI6.INP
BAI6.OUT
abc

0
abacdc
3
2.4. Hiệu quả của sáng kiến kinh nghiệm đối với hoạt động giáo dục, với
bản thân, đồng nghiệp và nhà trường
Qua quá trình áp dụng sáng kiến vào q trình giảng dạy đội tuyển học
sinh giỏi tơi nhận thấy sự tiến bộ rõ rệt của học sinh khi làm các bài tập liên
quan đến kiểu dữ liệu xâu, các em tự tin trong các kì thi học sinh giỏi và thường
đạt điểm tối đa ở các dạng bài tốn này. Hiệu quả thể hiện rõ qua kì thi học sinh
giỏi cấp trường và cấp tỉnh năm học 2020 - 2021 do tôi giảng dạy và bồi dưỡng:
- Đạt 01 giải Nhất kì thi học sinh giỏi cấp trường khối 11 năm học 2020 - 2021.
- Đạt 01 giải Nhất kì thi học sinh giỏi cấp trường khối 12 năm học 2020 - 2021.
- Đạt 01 giải Ba kì thi học sinh giỏi cấp Tỉnh năm học 2020 - 2021.
3. Kết luận, kiến nghị:
3.1. Kết luận:
16


Người giáo viên khi đã chọn nghề dạy học là phải có tâm yêu nghề, tâm
huyết với nghề, để có được kết quả thành cơng tốt đẹp thì mỗi người giáo viên
ln tìm tịi, sáng tạo, trăn trở và nổ lực không ngừng với nhiều cách thức và
phương pháp tối ưu nhất theo mình để giảng dạy, bồi dưỡng cho các em.
Phương pháp giảng dạy thì phong phú, kiến thức thì mênh mơng rộng lớn
vơ cùng, nhất là kiến thức gắn với yêu cầu đề thi của học sinh giỏi. Vì vậy trong
giới hạn của chun đề này, tơi chỉ khiêm tốn đưa ra một vài suy nghĩ về phương
pháp của mình để bồi dưỡng học sinh giỏi có hiệu quả. Hy vọng rằng những nội
dung trong chuyên đề này sẽ là những thông tin để được các đồng nghiệp trao
đổi, thảo luận để mong rút ra được những kinh nghiệm thực sự quý báu trong
công tác bồi dưỡng học sinh giỏi.
3.2. Kiến nghị:

Thư viện nhà trường cần bổ sung thêm sách tham khảo, các chuyên đề bồi
dưỡng HSG, Tuyển tập các đề thì Olympic các năm, các tạp chí Tin học và nhà
trường . . . có sử dụng NNLT C++ cho giáo viên cũng như cho học sinh tham
khảo phục vụ tốt hơn trong việc giảng dạy và học tập.

XÁC NHẬN CỦA
THỦ TRƯỞNG ĐƠN VỊ

Thanh Hóa, ngày 10 tháng 05 năm 2021
Tôi xin cam đoan đây là sáng kiến kinh
nghiệm của mình viết, khơng sao chép nội dung
của người khác.
Người viết

Bùi Thị Vân

17


TÀI LIỆU THAM KHẢO
1.
2.

[1] Đề thi học sinh giỏi tỉnh Thanh Hóa, năm 2020 - 2021.
[2] Đề thi học sinh giỏi tỉnh Thanh Hóa, năm 2018 - 2019.
3.
Giải bài trực tuyến (SPOJ)
4.
VNOI - Diễn đàn tin học, thuật toán o
5.

Giải thuật và lập trình, Lê Minh Hồng, Đại học Sư phạm Hà Nội, 1999 2002.
6.
Sách giáo khoa chuyên Tin quyển 2, Hồ Sĩ Đàm (Chủ biên), Đỗ Đức
Đông, Lê Minh Hoàng, Nguyễn Thanh Hùng, NXB Giáo dục, 2009
7.
Sách giáo khoa chuyên Tin quyển 3, Hồ Sĩ Đàm (Chủ biên), Đỗ Đức
Đơng, Lê Minh Hồng, Nguyễn Thanh Hùng, NXB Giáo dục, 2009


DANH MỤC
SÁNG KIẾN KINH NGHIỆM ĐÃ ĐƯỢC HỘI ĐỒNG SÁNG KIẾN KINH
NGHIỆM NGÀNH GIÁO DỤC VÀ ĐÀO TẠO HUYỆN, TỈNH VÀ CÁC
CẤP CAO HƠN XẾP LOẠI TỪ C TRỞ LÊN
Họ và tên tác giả: Bùi Thị Vân
Chức vụ và đơn vị công tác: Trường THPT Vĩnh Lộc

TT

1.
2.
3.
4.
5.
...

Tên đề tài SKKN

Cấp đánh giá
xếp loại
(Ngành GD cấp

huyện/tỉnh;
Tỉnh...)

Kết quả
đánh giá
xếp loại
(A, B,
hoặc C)

Năm
học
đánh
giá
xếp
loại



×