Báo cáo Biện pháp Vận dụng kiến thức về kiểu dữ liệu xâu trong việc lập trình giải các bài toán bằng ngôn ngữ C++

Trong kỳ thi HSG môn tin học ở hầu khắp các tỉnh thành thì các bài tập phần kiểu xâu kí tự có vai trò quan trọng. Kiểu dữ liệu xâu kí tự làphần rất nhiều vấn đề và rất nhiều bài tập phong phú, nếu giáo viên không lựa chọn mà cứ dạy tràn lan hoặc lựa chọn những bài khó vượt quá mức độ tư duy của các em ngay từ đầu thì với các em có mức độ tư duy trung bình khá hoặc khá sẽ khó có thể hiểu và học tốt được, dễ dẫn đến việc các em chán nãn.

Từ thực tiễn giảng dạy và bồi dưỡng học sinh giỏi, cùng với kinh nghiệm trong quá trình giảng dạy, bồi dưỡng học sinh. Tôi đã tổng hợp, khai thác để xây dựng đề tài: ‘‘Lựa chọn một số dạng bài tập kiểu xâu kí tự để bồi dưỡng cho học sinh đội tuyển môn Tin học ở trường THPT Hồng Lĩnh.

Qua nội dung đề tài này tôi mong muốn cung cấp cho học sinh một số dạng bài toán cơ bản về kiểu dữ liệu xâu kí tự, phương pháp và các kỹ năng cơ bản để học sinh có thể giải quyết chúng, tránh tình trạng khi các em gặp phải các bài toán tương tự hoặc bài toán đảo của bài toán đã làm liên quan đến kiểu dữ liệu xâu lại suy diễn, thường làm phức tạp vấn đề hay không giải được.Và trên cơ sở đó với tinh thần tự học một cách nghiêm túc thì các em có thể phát triển thêm tư duy của mình. Hy vọng kinh nghiệm nhỏ này sẽ giúp các học sinh có cái nhìn linh hoạt và chủ động khi gặp một số dạng bài toán liên quan đến kiểu xâu kí tự.

docx 15 trang Chăm Nguyễn 22/06/2025 330
Bạn đang xem tài liệu "Báo cáo Biện pháp Vận dụng kiến thức về kiểu dữ liệu xâu trong việc lập trình giải các bài toán bằng ngôn ngữ C++", để tải tài liệu gốc về máy hãy click vào nút Download ở trên.

Tóm tắt nội dung tài liệu: Báo cáo Biện pháp Vận dụng kiến thức về kiểu dữ liệu xâu trong việc lập trình giải các bài toán bằng ngôn ngữ C++

Báo cáo Biện pháp Vận dụng kiến thức về kiểu dữ liệu xâu trong việc lập trình giải các bài toán bằng ngôn ngữ C++
t chúng, tránh tình trạng khi các em gặp phải các bài toán tương tự hoặc bài toán đảo của bài toán đã làm liên quan đến kiểu dữ liệu xâu lại suy diễn, thường làm phức tạp vấn đề hay không giải được. Và trên cơ sở đó với tinh thần tự học một cách nghiêm túc thì các em có thể phát triển thêm tư duy của mình. Hy vọng kinh nghiệm nhỏ này sẽ giúp các học sinh có cái nhìn linh hoạt và chủ động khi gặp một số dạng bài toán liên quan đến kiểu xâu kí tự.
NỘI DUNG BIỆN PHÁP
KHÁI NIỆM:
Xâu là một dãy kí tự trong bảng mã ASCII. Mỗi kí tự được gọi là một phần tử của xâu.
Số lượng kí tự trong xâu được gọi là độ dài xâu.
Xâu có độ dài bằng 0 gọi là xâu rỗng.
(Lưu ý: Ta có thể xem xâu như là mảng một chiều mà mỗi phần tử kiểu kí t
Tham chiếu đến một phần tử của xâu: S[Chỉ số]
Ví dụ: Với xâu S = “Le_Thanh_Huy”. Ta có: S[3] là ‘T’, S[0] = ‘L’
* Khai báo:
string ; Ví dụ: string s;
Các kí tự trong xâu được đánh chỉ số bắt đầu từ 0.
CÁC THAO TÁC LÀM VIỆC VỚI BIẾN XÂU:
* So sánh hai xâu:
Quy tắc:
- Hai xâu bằng nhau nếu chúng giống nhau hoàn toàn: (Phân biệt hoa thường)
Ví dụ: “Hona” = “Hona”
Nhưng “hona” ≠ “HONA”
- Hai xâu khác nhau: Ta sẽ kiểm tra kí tự khác nhau đầu tiên của hai xâu tính từ bên trái sang,
nếu kí tự nào có mã ASCII lớn hơn thì xâu đó lớn hơn

Giải thích: Kí tự khác nhau đầu tiên tính từ bên trái sang là n và
m. Mà m có mã ASCII lớn hơn nên xâu “Amh” lớn hơn.
Ví dụ: “Anh” < “Amh”
Chú ý: - ‘A’ có mã ASCII là 65, ‘B’ là 66
‘a’ có mã ASCII là 97 
Ghép xâu: Sử dụng toán tử += hoặc + Ví dụ: s = "Chao";
s +=" ban";
Các hàm và thủ tục xử lý xâu:
Lấy độ dài xâu: Hàm length() hoặc size()
s = “chao”;
cout <<s.size();
Kết quả: 4
Xóa phần tử trong xâu: Hàm erase(từ vị trí , số kí tự cần xoá);
s = “chao ban”; s.erase(0, 5);
Kết quả: s = “ban”;
Chèn thêm vào xâu: Hàm insert s = “Chao ban”; s.insert(0, “Xin ”); Kết quả: s = “Xin chao ban”;
S = “Chao ban”; R = “ Huy”; S.insert(8, R);
Kết quả: S = “Chao ban Huy”;
S = “Chao ban”;
R = “ Huy”;
S.insert(8, R, 2, 2);
Kết quả: S = “Chao ban uy”;
Sao chép xâu: Hàm substr
S = “Chao ban”;
R = S.substr(1, 3);
Kết quả: R = “hao”
Tìm kiếm: Hàm find sẽ trả về vị trí đầu tiên xuất hiện, nếu không tìm thấy sẽ trả về vị trí string::npos
s = "Chao ban"; if(s.find("ban") != string::npos) cout <<"YES";
Đáp án: in ra YES
Tương tự có: rfind tìm kiếm vị trí xuất hiện cuối cùng
Thay thế: Hàm replace(pos, len, str2); s = "Chao ban";
s.repalce(1,4,’hu’);
Thay thế len kí tự từ kí tự pos bằng str2
Chuyển từ xâu sang số:
(Tương tự có: stof, stol, stoll, stoull) (Đáp án y là tổng của hai xâu số)
x = stoi(s);
y = stoll(s+r);
Chuyển từ số sang xâu: Số x
Qua xâu: (Cách chuẩn hiện tại, nên dạy khi bồi dưỡng HSG) ostringstream ss;
ss << num; string s = ss.str();
in hoa một xâu:
for(int i=0; i<s.size(); i++) s[i] = toupper(s[i]); //in hoa
in thường xâu s:
for(int i=0; i<s.size(); i++) s[i] = tolower(s[i]); //in thuong
BÀI TẬP CHỦ ĐỀ XỬ LÝ XÂU
Bài 1: Tìm kiếm và thay thế:
Trong khi soạn thảo văn bản một số người thường có thói quen gõ tắt cho nhanh nhưng với văn bản hành chính các từ này là không hợp lệ, một số khác lại thường xuyên gõ lỗi 1 số từ nào đó. Để sửa những lỗi này các phần mềm soạn thảo đều có chức năng tìm kiếm và thay thế.
Vậy em hãy viết chương trình nhập vào từ bàn phím xâu ký tự s, tìm và thay thế tất cả các cụm ký tự s1 thành s2.
Ví dụ:	Xâu gốc: s = “HS lop 12 thi HS gioi”
s1= “HS”; s2= “Hoc sinh”;
Xâu kết quả: S = “Hoc sinh lop 12 thi Hoc sinh gioi”
Hướng dẫn:
Cách 1:
Dùng hàm tìm kiếm s.find(s1) để xác định vị trí xuất hiện xâu s1 trong xâu
s:vt = s.find(s1) Nếu vt != -1 tức là có xâu s1 trong xâu s thì thay thế xâu s1 bởi xâu s2 bằng hàm s.replace(vt,l1,s2); hoặc thay thế bằng lệnh xóa và chèn: s.erase(vt,l1); s.insert(vt,s2);
Lưu ý: Trong xâu có thể có rất nhiều cụm từ cần thay thế nên ta phải sử dụng lệnh while để thay thế hết: trong khi s.find(s1) != -1 thì tiếp tục thay thế
Cách 2:
Để duyệt hết tất cả các khả năng cần thay thế ta sử dụng lệnh for kết hợp lệnh s.substr() để sao chép từng đoạn con có độ dài bằng độ dài xâu s1 rồi so sánh với s1. Nếu kết quả bằng s1 thì ta tiến hành thay thế bằng các câu lệnh tương tự cách 1.
Chương trình:
Cách 1
Cách 2
#include using namespace std;
int main()
{
string s,s1,s2; getline(cin,s); getline(cin,s1); getline(cin,s2); int k=s1.size();
while(s.find(s1)!=-1){ int vt=s.find(s1); s.replace(vt,k,s2);
}
cout<<s; return 0;
}
#include using namespace std;
int main()
{
string s,s1,s2; getline(cin,s); getline(cin,s1); getline(cin,s2); int k=s1.size();
for(int i=0;i<s.size()-k;i++){
if(s.substr(i,k)==s1){
s.replace(i,k,s2);
}
}
cout<<s; return 0;
}

Bài 2: Chuyển đổi phông chữ:
Khi soạn thảo và trình bày văn bản, việc chuyển đổi đoạn văn chữ hoa sang thường hay chữ thường sang chữ hoa là một nhu cầu rất phổ biến. Trong hệ soạn thảo văn bản Word, nếu ta dùng bảng mã TCVN3 thì việc chuyển đổi rất đơn giản, chỉ cần chọn lại phông chữ tương ứng còn khi dùng bảng mã Unicode thì ta phải sử dụng công cụ chuyển đổi của phần mềm hỗ trợ gõ chữ việt.
Em hãy viết chương trình nhập vào 1 xâu ký tự s, tạo xâu s1 chứa các từ trong xâu s nhưng ở dạng chữ hoa, tạo xâu s2 chứa các tự trong xâu s nhưng ở dạng chữ thường. Xuất kết quả xâu s1, s2 ra màn hình.
Hướng dẫn:
Cách 1: Dùng hàm toupper(), tolower() để chuyển đồi từng ký tự.
Duyệt từng ký tự của xâu s, với mỗi ký tự đó ta dùng hàm toupper() chuyển sang ký tự hoa rồi nối vào xâu s1, dùng hàm tolower() chuyển sang chữ thường rồi nối vào xâu s
Hoặc gán s1 = s; s2 =s; sau đó duyệt từng ký tự của xâu s1 dùng hàm toupper() chuyển sang ký tự hoa, duyệt từng ký tự của xâu s2 dùng hàm tolower() đê chuyển sang ký tự thường Cách 2: Dùng hàm transform() để chuyển đồi tất cả các ký tự.
- transform(s1.begin(), s1.end(),s1.begin(), ::toupper); chuyển tất cả các ký tự trong xâu s1 thành chữ hoa.
- transform(s2.begin(), s2.end(),s2.begin(), ::tolower); chuyển tất cả các ký tự trong xâu s2 thành chữ thường.
Chương trình:
Cách 1
Cách 2
#include using namespace std; int main()
{
string s,s1,s2; getline(cin,s); s1="";
s2="";
char c;
for(int i=0;i<s.size();i++){ c=toupper(s[i]); s1=s1+c; c=towlower(s[i]); s2=s2+c;
}
cout<<s1<<"\n"; cout<<s2;
return 0;
}
#include using namespace std;
int main()
{
string s,s1,s2; getline(cin,s); s1=s;
s2=s; transform(s1.begin(),s1.end(),s1.begin(),::toupper);
transform(s2.begin(),s2.end(),s2.begin(),::towlower); cout<<s1<<"\n";
cout<<s2; return 0;
}
Bài 3: Công tác quản lý thi:
Trong công tác tổ chức các kỳ thi, để đảm bảo tính khách quan, công bằng cho các thí sinh, một công đoạn hết sức quan trọng là lập danh sách dự thi và đánh số báo danh. Để đánh số báo danh, danh sách phải được sắp xếp với tên theo bảng chữ cái.
Em hãy viết chương trình giúp cán bộ làm công tác thi, nhập vào số nguyên n là số lượng thí sinh, sau đó đưa vào họ và tên của n thí sinh, đưa ra danh sách thí sinh đó nhưng đã được sắp xếp với tên theo bảng chữ cái.
Hướng dẫn:
Dùng mảng hoten để lưu danh sách thí sinh: hoten[i] ghi họ và tên thí sinh i.
Với mỗi thí sinh i, tách lấy phần tên lưu vào mảng: ten[i]
Sắp xếp mảng tên theo thứ tự tăng dần, với mỗi lượt tráo đổi 2 phần tử trong mảng tên thì tráo đổi luôn 2 phần tử tương ứng trong mảng hoten.
Xuất ra kết quả là danh sách thí sinh trong mảng hoten
#include using namespace std; struct thisinh{
string hoten; string ten;
};
bool comp(thisinh a, thisinh b){ return a.ten<b.ten;
}
int main()
{
int n; cin>>n;
cin.ignore(32767,'\n'); thisinh s[n];
int l; int j;
for(int i=0;i<n;i++){ getline(cin,s[i].hoten);
l=s[i].hoten.size(); j=l-1;
while(s[i].hoten[j]!=' '){
Chương trình tham khảo
j--;
}
s[i].ten=s[i].hoten.substr(j+1,l-j);
}
sort(s,s+n,comp); for(int i=0;i<n;i++){
cout<<s[i].hoten; cout<<"\n";
}
return 0;
}
Bài 4: Đếm số lần xuất hiện mỗi loại ký tự.
Cho xâu s (có độ dài không vượt quá 103) chỉ gồm các ký tự từ 'A' đến 'Z'. Cho biết có bao nhiêu loại ký tự xuất hiện trong s và đưa ra một ký tự xuất hiện nhiều nhất trong s cùng với số lần xuất hiện của ký tự đó
Hướng dẫn:
Các ký tự từ 'A' đến 'Z' có mã ASCII tương ứng từ 65 đến 90. Nên ta sử dụng mảng T gồm 91 phần tử với kiểu chỉ số từ 0 đến 90, kiểu giá trị int để lưu số lần xuất hiện: T[65]
T[90] tương ứng số lần xuất hiện ký tự ‘A’ ‘Z’.
Lần theo các giá trị của mảng T trên đoạn từ 65 đến 90 ta được số lượng các ký tự khác nhau (tức số lượng phần tử có giá trị khác 0 trong mảng T) và tìm giá trị lớn nhất của mảng T ta sẽ tìm được ký tự xuất hiện nhiều lần nhất.
Về nguyên tắc, ta chỉ cần sử dụng mảng với 26 phần tử kiểu int với chỉ số từ 0 đến 25, khi đó với mỗi ký tự ta chuyển sang mã ASCII rồi dịch chuyển chỉ số 65 đơn vị để lưu vào đầu mảng.
#include using namespace std;
int main()
{
string s; getline(cin,s);
Chương trình
int t[91];
for(int i=65;i<=90;i++){ t[i]=0;
}
for(int i=1;i<s.size();i++){ t[s[i]]++;
}
int dem=0; int max=65;
for(int i=65;i<=90;i++){ if(t[i]!=0){
dem++; if(t[max]<t[i]){
max=i;
}
}
}
cout<<dem<<"\n"; cout<<char(max)<<" "<<t[max]; return 0;
}
Bài 5: Mã hóa Xê Da (sách bài tập tin học 11)
Để giữ bí mật người ta phải mã hóa các thông tin trước khi truyền đi hoặc lưu trữ. Một trong những cách mã hóa sớm nhất được sử dụng rộng rãi thời cổ đại là cách mã hóa do Xê Da đề xuất: trong thông điệp, người ta thay đổi chữ cái bằng chữ cái đứng sau nó K vị trí trong bảng chữ cái. Việc tìm kiếm thay thế được tiến hành vòng tròn theo bảng chữ cái. Nếu bảng chữ cái có N chữ, thì sau chữ cái thứ N-1 là chữ cái N, sau chữ cái N là chữ cái thứ nhất, Cách mã hóa này gọi là mã Xê Da. Các kí tự ngoài bảng chữ cái vẫn được giữ nguyên.
Ví dụ, bảng chữ cái tiếng Anh có 26 chữ cái. Nếu K = 2 thì có nghĩa là a được thay thế bằng c, b được thay thế bằng d, . . ., y được thay thế bằng a, z được thay thế
bằng b. Các chữ cái in hoa sẽ được thay thế bằng chữ cái in hoa tương ứng. Trong trường hợp này, từ ‘TIN HOC’ sẽ được mã hóa thành ‘VKP JQE’ .
Hãy lập trình: Nhập vào từ bàn phím số nguyên K (1<K<=26) và xâu S không quá 255 kí tự. Mã hóa theo quy tắc mã Xê Da và đưa kết quả ra màn hình.
Hướng dẫn:
Để dễ xử lý hơn khi dịch k ký tự theo vòng tròn, ta dùng thêm 2 biến phụ S1 để lưu 2 lần bảng chữ cái in hoa. S2 lưu 2 lần bảng chữ cái in thường.
Duyệt từng ký tự trong xâu s, tìm vị trí xuất hiện của nó trong xâu s1, s2. Nếu tìm thấy thì ta lấy ký tự cách nó k ký tự trên mảng tương ứng.
#include using namespace std;
int main()
{
int n; cin>>n; string s;
cin.ignore(32767,'\n'); getline(cin,s);
string s1=""; string s2="";
for(int i=65;i<=90;i++){ s1=s1+char(i); s2=s2+char(i+32);
}
s1=s1+s1+s2+s2; string ans="";
for(int i=0;i<s.size();i++){ int vt=s1.find(s[i]); if(vt==-1){
ans=ans+s[i];
}
Chương trình tham khảo
else{
ans=ans+s1[vt+n];
}
}
cout<<ans; return 0;
}
Bài 6: Xâu con dài nhất
Cho xâu S, tìm xâu con liên tục dài nhất của xâu S mà không chứa chữ số nào. Kết quả đưa ra vị trí đầu và xâu con đó. Nếu có nhiều xâu con dài nhất thì đưa ra xâu đầu tiên.
Hướng dẫn:
Có rất nhiều giải thuật để duyệt tìm xâu con dài nhất thỏa mãn một điều kiện nào
đó.
Cách 1: Duyệt vét cạn thử với mọi xâu con để tìm xâu con dài nhất.
Sử dụng hai vòng for lồng nhau duyệt từ đầu đến hết xâu với mỗi cặp chỉ số đầu i và chỉ số j. Ta kiểm tra có thỏa mãn điều kiện hay không, rồi so sánh tìm xâu con thỏa
mãn dài nhất.
Cách 2: Duyệt theo các xâu con với độ dài từ lớn đến bé.
Ta duyệt các xâu con với độ dài từ độ dài xâu mẹ giảm dần. Khi gặp xâu con đầu tiên thỏa mãn điều kiện thì đây chính là xâu cần tìm và ta kết thúc việc duyệt bằng lệnh break;
Cách 3: Duyệt phát triển xâu con:
Lần lượt duyệt lần lượt các ký tự trong xâu, dùng biến lmax để lưu độ dài xâu lớn nhất đã tìm được, nếu gặp ký tự thỏa mãn (không phải số) ta tăng dần độ dài xâu con. Khi gặp ký tự không thỏa mãn (ký tự số) thì ta thu được một xâu con thỏa mãn điều kiện, đem độ dài xâu này so sánh với lmax đã lưu để cập nhật lại lmax mới.
Với bài toán này ta sử dụng cách 3 duyệt theo phát triển xâu con với độ phức tạp o(n).
#include using namespace std;
Chương trình tham khảo
int main()
{
string s; getline(cin,s); int lmax=0; int l=0;
int c;
for(int i=0;i<s.size();i++){ if(isdigit(s[i])==false){
l++;
}
else{
if(lmax<l){ c=i; lmax=l;
} l=0;
}
}
string k=s.substr(c-lmax,lmax); cout<<lmax<<" "<<k;
return 0;
}
Bài 7: Đếm xâu con (có chồng lấn và không chồng lấn lên nhau)
Viết chương trình nhập vào 2 xâu ký tự s1, s2. Hãy cho biết số lần xuất hiện xâu s2 trong xâu s1 không chồng lấn và số lần xuất hiện xâu s2 trong s1 có chồng lấn.
Ví dụ:	s1= “ababababaab”	S2= “aba” Kết quả:	Số lần xuất hiện không chồng lấn là: 2
Số lần xuất hiện có chồng lấn là: 4
Hướng dẫn:
Cách 1: Sử dụng hàm tìm kiếm sự xuất hiện xâu s2 trong xâu s1. Khi tìm thấy s2 trong s1, ta xóa (hoặc thay thế bởi xâu “”) toàn phần tìm thấy hoặc 1 ký tự tại vị trí tìm thấy rồi tìm tiếp. Nếu dung câu lệnh find() có tham số vị trí bắt đầu thì không cần xóa.
Cách 2: Ta có thể dùng lệnh while duyệt sao chép đoạn con của s1 có độ dài bằng l2 (độ dài xâu s2) để so sánh với s2, trong yêu cầu 1 nếu tìm thầy thì ta nhảy qua l2 vị trí tiếp theo.
#include using namespace std; int main()
{
string s; string s1; getline(cin,s);
getline(cin,s1); int vt=s.find(s1);
int ans=0; int k;
while(vt!=-1){ ans++; k=vt+1;
vt=s.find(s1,k);
}
cout<<ans<<" "; ans=0; vt=s.find(s1); while(vt!=-1){
ans++; s.replace(0,vt+s1.size(),""); vt=s.find(s1);
}
cout<<ans; return 0;
}
Chương trình tham khảo
KẾT LUẬN CHUNG
Hiện nay hầu hết các lĩnh vực trong xã hội đã ứng dụng CNTT để giải quyết các công việc một cách nhanh chóng, chính xác và hiệu quả hơn. Trong đó, các ngôn ngữ lập trình, các nhà lập trình chuyên nghiệp đóng vai trò rất quan trọng trong việc xây dựng các chương trình ứng dụng để phục vụ cho cuộc sống. Bởi vậy, việc phát hiện những học sinh có năng lực, yêu thích lập trình và bồi dưỡng HSG Tin học trở thành một việc làm quan trọng và cấp thiết, góp phần phát triển đội ngũ lập trình viên, phát triển nền kinh tế, tri thức của đất nước.
HIỆU QUẢ CỦA BIỆN PHÁP
Các em khắc sâu kiến thức cơ bản về kiểu xâu sách giáo khoa. Kỹ năng lập trình của các em tăng lên đáng kể, đặc biệt là hứng thú học tập, các em định hướng rõ hơn về một dạng bài tập, tạo cho các em tâm lý không sợ khó khi gặp bài tập dạng này.
Năng lực phân tích, nhận dạng và lựa chọn được thuật toán thích hợp để giải quyết các bài toán về xâu.
Khả năng đánh giá độ phức tạp của thuật toán, biết sử dụng phần mềm Themis để kiểm tra tốc độ của chương trình.
Khả năng tư duy thuật toán, phát huy tính sáng tạo.
Năng lực vận dụng các kiến thức đã học vào giải quyết vấn đề.
Trình bày thuật toán, diễn đạt chương trình rõ ràng, chuẩn xác.
Hăng say học tập, nghiên cứu, làm việc khoa học.

File đính kèm:

  • docxbao_cao_bien_phap_van_dung_kien_thuc_ve_kieu_du_lieu_xau_tro.docx
  • pdfBáo cáo Biện pháp Vận dụng kiến thức về kiểu dữ liệu xâu trong việc lập trình giải các bài toán bằng.pdf