Trong Pascal cũng như các NNLT khác, dữ liệu trong bài toán không chỉ là dữ liệu kiểu số mà còn có kiểu dữ liệu phi số. Kiểu xâu là một trong các kiểu dữ liệu được giới thiệu trong sách giáo khoa tin học 11. Tuy nhiên, thời lượng chỉ có 2 tiết nên học sinh chưa được tìm hiểu sâu và làm nhiều bài tập về kiểu dữ liệu này. Mặt khác, trong thực tế có nhiều bài toán chỉ có thể dùng kiểu xâu mới giải quyết được. Không những thế trong các đề thi học sinh giỏi lớp 11 và 12 có nhiều bài toán liên quan đến việc sử dụng kiểu dữ liệu xâu. Để giải quyết được những bài toán này không những đòi hỏi học sinh phải có kiến thức cơ bản về xâu mà còn phải nắm bắt được và vận dụng linh hoạt các thao tác xử lí xâu và một số thuật toán phức tạp khác. Tôi chọn đề tài “Đi sâu tìm hiểu các dạng bài toán kiểu xâu” với mong muốn giúp học sinh có thêm tài liệu để có thể hiểu rõ, sâu hơn về kiểu dữ liệu xâu.
Trang 1A PHẦN MỞ ĐẦU
1 Lí do chọn đề tài
Trong Pascal cũng như các NNLT khác, dữ liệu trong bài toán không chỉ là
dữ liệu kiểu số mà còn có kiểu dữ liệu phi số Kiểu xâu là một trong các kiểu dữliệu được giới thiệu trong sách giáo khoa tin học 11 Tuy nhiên, thời lượng chỉ có
2 tiết nên học sinh chưa được tìm hiểu sâu và làm nhiều bài tập về kiểu dữ liệunày Mặt khác, trong thực tế có nhiều bài toán chỉ có thể dùng kiểu xâu mới giảiquyết được Không những thế trong các đề thi học sinh giỏi lớp 11 và 12 có nhiềubài toán liên quan đến việc sử dụng kiểu dữ liệu xâu Để giải quyết được những bàitoán này không những đòi hỏi học sinh phải có kiến thức cơ bản về xâu mà cònphải nắm bắt được và vận dụng linh hoạt các thao tác xử lí xâu và một số thuậttoán phức tạp khác
Tôi chọn đề tài “Đi sâu tìm hiểu các dạng bài toán kiểu xâu” với mong muốn
giúp học sinh có thêm tài liệu để có thể hiểu rõ, sâu hơn về kiểu dữ liệu xâu
2 Mục đích nghiên cứu
Giúp học sinh nắm được các kiến thức về kiểu xâu từ đó giải được các bàitập cơ bản và nâng cao về nó
3 Nhiệm vụ nghiên cứu
• Tìm hiểu các kiến thức về kiểu dữ liệu xâu
• Đưa ra được các dạng bài tập về kiểu dữ liệu xâu và giải quyết nó
4 Phạm vi nghiên cứu
• Cách khai báo dữ liệu kiểu xâu
• Các thao tác xử lí xâu
• Một số bài tập cơ bản về xâu
• Các bài tập nâng cao được chon lọc
5 Phương pháp nghiên cứu
• Phương pháp nghiên cứu lý thuyết: nghiên cứu sách, báo và các tài liệu điệntử
• Phương pháp phỏng vấn chuyên gia: tiếp thu ý kiến cố vấn, đánh giá củacác giáo viên có kinh nghiệm
Trang 2• Tham khảo ý kiến của đồng nghiệp.
6 Nội dung
Chương 1: Các kiến thức cơ bản về kiểu xâu
Tìm hiểu cách khai báo và các thao tác xử lí xâu
Chương 2: Một số dạng bài tập về kiểu xâu
Giải quyết một số bài tập kiểu xâu (theo dạng) thường gặp
Trang 3B PHẦN NỘI DUNG CHƯƠNG I: CÁC KIẾN THỨC CƠ BẢN VỀ KIỂU XÂU
1.1 Khái niệm
- Xâu: Là dãy các kí tự trong bộ mã ASCII, mỗi kí tự là một phần tử của xâu
- Độ dài xâu: Số lượng kí tự trong xâu được gọi là độ dài xâu
- Xâu rỗng: Xâu có độ dài bằng 0 gọi là xâu rỗng
1.2 Khái báo
- Gián tiếp:
Type <tên kiểu xâu> = string[độ dài lớn nhất của xâu];
Var <tên biến xâu> : <tên kiểu xâu>;
- Trực tiếp:
Var <tên biến xâu> : string[độ dài lớn nhất của xâu];
1.3 Nhập, xuất dữ liệu kiểu xâu
- Nhập, xuất biến xâu:
Có thể sử dụng các thủ tục xuất nhập Write, Writeln, Read, Readln để xuất, nhập các biến kiểu String.
- Truy cập đến từng phần tử của xâu: <tên biến xâu>[chỉ số]
Trang 4- Thủ tục delete(st,vt,n) Thực hiên việc xóa n kí tự của biến xâu st, bắt đầu từ vị trí
vt
- Thủ tục insert(s1,s2,vt) chèn xâu s1 vào xâu s2 bắt đầu ở vị trí vt
- Thủ tục str(num, st) đổi số nguyên hay thực num thành dạng xâu ký tự, kết quả
lưu vào biến st.
- Thủ tục val(st:string, num, code) đổi xâu số st thành số và gán kết quả lưu vào
biến num Nếu việc chuyển đổi thành công thì biến code có giá trị là 0, ngược lại biến code có giá trị khác 0 (vị trí của lỗi).
- Ham copy(s,vt,n) tạo xâu gồm n kí tự liên tiếp bắt đầu từ vị trí vt của xâu s
- Hàm length(s) cho giá trị là độ dài xâu s
- Hàm pos(s1,s2) cho vị trí xuất hiện đầu tiên của xâu s1 trong xâu s2
- Hàm upcase(ch) cho chữ cái in hoa ứng với chữ cái ch
- Hàm chr(x) cho giá trị là kí tự có mã ASCII thập phân bằng x
- Hàm ord(ch) cho giá trị mã ASCII thập phân của kí tự ch
Trang 5CHƯƠNG II: MỘT SỐ DẠNG BÀI TẬP VỀ KIỂU XÂU
Cho tệp văn bản XEDA.INP có cấu trúc như sau:
- Dòng 1: ghi số nguyên K (1<k<26)
- Dòng 2: Xâu S1
- Dòng 3: Xâu S2
Các xâu S1, S2 không quá 255 kí tự
Hãy lập trình đọc dữ liệu từ tệp trên, thực hiện mã hóa xâu S1 theo quy tắc Xê Da
và giải mã xâu S2 (S2 là xâu đã được mã hóa theo quy tắc Xê Da) Kết quả ghi vàotệp XEDA.OUT
Ý tưởng:
- Viết chương trình con mã hóa 1 kí tự từ đó thực hiện mã hóa cả xâu kí tự
- Viết chương trình con giải mã 1 kí tự từ đó giải mã cả xâu kí tự
Chương trình:
var S1,S2,S,sg:string;
g:text;
k:integer;
Trang 6function mahoa(x : char) : char;
var vtri : byte;
function giaima(x : char) : char;
var vtri : byte;
Trang 7Cho trước khoá là một hoán vị của n số (1, 2, , n) Khi đó để mã hoá một xâu kí
tự ta có thể chia xâu thành từng nhóm n kí tự (riêng nếu nhóm cuối cùng không đủ
n kí tự thì ta có thể thêm các dấu cách vào sau cho đủ) rồi hoán vị các kí tự trongtừng nhóm Sau đó, ghép lại theo thứ tự các nhóm ta được một xâu đã mã hoá
Dữ liệu vào được cho bởi tệp MHKHOA.INP gồm 3 dòng
if (Length(S) Mod n) <>0 then
For i:=1 to n-(Length(S) Mod n) do S:=S+' ';
KQ:='';
For i:=0 to (Length(S) Div n)-1 do
For j:=(n*i)+1 to n*(i+1) do
Trang 8BT3: Nén xâu (mã hóa loạt dài)
(Đề thi chọn học sinh giỏi tỉnh lớp 12 – Năm học 2010-2011)
Một xâu kí tự có thể được nén theo cách sau: một xâu con gồm n kí tự giống
nhau (n>1), chẳng hạn gồm n kí tự “a” sẽ được ghi thành na.
Yêu cầu:
a) Với một xâu kí tự cho trước không có các chữ số, hãy nén xâu đó theo cách
đã nêu
b) Hãy giải nén một xâu kí tự sau khi đã được nén theo cách đã nêu
Dữ liệu vào: tệp XAU INP có cấu trúc
- Dòng đầu tiên chứa xâu S không quá 254 kí tự và không có các chữ số
- Dòng thứ hai chứa xâu X không quá 254 kí tự là xâu nén của một xâu nàođó
Dữ liệu ra: tệp XAU.OUT có cấu trúc
- Dòng đầu tiên chứa xâu nén của xâu S
- Dòng thứ hai chứa xâu đã giải nén của xâu X
Ví dụ:
Aaaabbcd3a4b2c
4a2bcdaaabbbbcc
Ý tưởng:
- Nén: Xác định đoạn liên tiếp có số các kí tự giống nhau là t Nếu t >1 thì thông
báo t và kí tự đó, còn không thì chỉ thông báo kí tự đó
Trang 9- Giải nén: Nếu X[i] là kí tự số thì chuyển X[i] sang số (so), thông báo kí tự X[i+1] so lần; còn không thì thông báo X[i+1] 1 lần
Trang 10(Đề thi chọn học sinh giỏi tỉnh lớp 11 – Năm học 2009-2010)
Xâu nhị phân là xâu chỉ chứa các kí tự 0 và 1 Để đảm bảo bí mật và tiếtkiệm dung lượng nhớ khi trao đổi thông tin với nhau, người ta có một cách để mãhóa xâu nhị phân như sau: với một xâu nhị phân S, mã hóa nó thành một dãy sốnguyên T (T1,T2,…,TM) được tạo ra theo nguyên tắc sau:
- Nếu kí tự đầu tiên của S là 0 thì T1 = 0, nếu là 1 thì T1=1
- Nếu T1 = 0 thì tính từ trái sang phải của xâu S, T2 bằng số kí tự 0 liên tiếp,T3 bằng số kí tự 1 liên tiếp sau đó, T4 bằng số kí tự 0 liên tiếp sau đó,…cho đến hết xâu S
- Nếu T1=1 thì tính từ trái sang phải của xâu S, T2 bằng số kí tự 1 liên tiếp,T3 bằng số kí tự 0 liên tiếp sau đó, T4 bằng kí tự 1 liên tiếp sau đó,… chođến hết xâu S
Ví dụ:
S= 0000110100111 T=(0,4,2,1,1,2,3)S=11110011001 T=(1,4,2,2,2,1)
Yêu cầu: với mỗi dãy số mã hóa T cho trước nào đó, hãy đưa ra xâu S là xâu nhị
phân được mã hóa bởi dãy số T
Dữ liệu vào: Tệp văn bản MAHOA.INP có cấu trúc
- Dòng đầu tiên ghi số M (M<50) là số lượng các số trong dãy số mã hóa T
- Dòng tiếp theo ghi M số trong dãy số mã hóa T, các số ghi cách nhau ít nhấtmột kí tự trống
Dữ liệu ra: Tệp văn bản MAHOA.OUT ghi xâu nhị phân S được mã hóa bởi dãy
Trang 11for j:=1 to a[i] do write(f2,1)
else for j:=1 to a[i] do write(f2,0);
Bài 1 Cho tệp văn bản XAU.INP chứa 1 xâu kí tự S Lập trình đọc xâu S và đếm
xem trong xâu S có bao nhiêu từ là đối xứng (Từ là một dãy các kí tự, cách nhau bởi dấu cách), kết quả ghi vào tệp XAU.OUT
Trang 12end;
function doixung(x : string) : boolean;
var y : string; i : integer;
begin
y := '';
for i := length(x) downto 1 do y := y + x[i];
if x=y then doixung := true
else doixung := false;
while (s[i]=' ') and (i<=len) do inc(i);
if i>=len then break;
Yêu cầu: Xác định số cách khác nhau có thể lắp khóa tháo lắp vòng
Input: Tệp HAT.INP có dạng:
Trang 13- Dòng 1 ghi các số nguyên từ 1 đến
9, số thứ i chỉ thị màu viên đá thứ i,
các số ghi liên tiếp nhau
Output: ghi ra tệp HAT.OUT
– Dòng 1 ghi Số cách khác nhau có thể lắp khóa, nếu không ghi số 0
– Dòng 2: ghi Vị trí lắp khóa
Ý tưởng:
• Nhân đôi xâu ban đầu
• Viết chương trình con kiểm tra 1 xâu có độ dài N có phải là đối xứng haykhông
• Kiểm tra từng xâu con độ dài N bắt đầu từ vị trí i (i= 1, ,N), nếu nó là xâuđối xừng thì đặt khóa tại vị trí i
Trang 14BT2: Robot công nghiệp
(Đề thi chọn học sinh giỏi tỉnh lớp 11 – Năm học 2010-2011)
Trong một nhà máy có trang bị loại Robot công nghiệp để thực hiện việc tựđộng hóa gia công các sản phẩm Việc gia công các sản phẩm của Robot được thựchiện đồng thời trên hai sản phẩm cùng một lúc theo tiến trình: với mỗi loại thao tácgia công được Robot thực hiện trên sản phẩm thứ nhất xong rồi chuyển sang thựchiện trên sản phẩm thứ hai Để hoàn thành một sản phẩm, Robot có thể thực hiệntới N loại thao tác gia công (N<=24) và mỗi loại thao tác gia công được thực hiệntrên một sản phẩm nào đó rồi thì không thực hiện lại trên sản phẩm đó nữa Robotthực hiện bằng lệnh là một dãy kí tự in hoa, mỗi kí tự là lệnh thực hiện cho mộtloại thao tác gia công Lệnh thực hiện các loại thao tác gia công khác nhau là các
kí tự khác nhau Việc đọc dòng lệnh và thực hiện lệnh của Robot được tiến hànhtheo các chu trình như sau:
- Chu trình thứ nhất: Đọc kí tự thứ nhất, thực hiện lệnh tương ứng trên sảnphẩm thứ nhất Tiếp theo đọc kí tự thứ N, thực hiện lệnh tương ứng trên sảnphẩm thứ hai
- Chu trình thứ hai: Đọc kí tự thứ hai, thực hiện lệnh tương ứng trên sản phẩmthứ nhất Tiếp theo đọc kí tự thứ N-1, thực hiện lệnh tương ứng trên sảnphẩm thứ hai
Trang 15- Chu trình thứ ba: Đọc kí tự thứ ba, thực hiện lệnh tương ứng trên sản phẩmthứ nhất Tiếp theo đọc kí tự thứ N-2, thực hiện lệnh tương ứng trên sảnphẩm thứ hai.
-
Tương tự với các chu trình còn lại để đọc hết dòng lệnh
Với một xâu S các kí tự in hoa có số lượng các kí tự là chẵn và không quá Nx2,hãy xác định xem nó có phải là một dòng lệnh của Robot đã nói ở trên hay không?
Dữ liệu vào: Tệp văn bản ROBOT.INP có cấu trúc:
- Dòng đầu tiên ghi một số là độ dài xâu S
- Dòng thứ hai ghi xâu S
Dữ liệu ra: Tệp văn bản ROBOT.OUT ghi thông báo ‘CO’ nếu xâu S là dòng lệnh
của Robot, ngược lại ghi thông báo ‘KHONG’
Ví dụTệp ROBOT.INP
Tệp ROBOT.OUT
6CBAABC
CO
Tệp ROBOT.INP Tệp ROBOT.OUT6
• Kiểm tra nửa đầu xâu S xem các kí tự có khác nhau không? Nếu nửa đầu xâu
mà các kí tự không khác nhua từng đôi một thì đưa ra kết luận xâu S khôngphải là lệnh của Robot và dừng thuật toán
• Nếu nửa đầu xâu S có các kí tự khác nhau từng đôi một thì kiểm tra tính đối xứng của xấu S
Chương trình:
Trang 16Dữ liệu: Vào từ file văn bản XAU.INP, gồm duy nhất 1 dòng ghi xâu S
Kết quả: Ghi ra file văn bản XAU.OUT, duy nhất số k là số kí tự ít nhất cần thêm
vào S để S trở thành xâu đối xứng Nếu xâu S đã cho là đối xứng thì ghi k = 0
Trang 17- Nhập xâu bất kì từ bàn phím
- Chuẩn hóa xâu theo các quy tắc sau:
+ Xóa các dấu cách ở đầu xâu nếu có
+ Xóa các dấu cách ở cuối xâu nếu có
+ Thay dãy nhiều dấu cách liên tiếp bằng một dấu cách
- Đưa kết quả đã chuẩn hóa ra màn hình
Ý tưởng:
• Thực hiện tìm từ đầu xâu đến cuối xâu, nếu có 2 dấu cách liên tiếp thì thực hiện xóa đi 1 dấu cách
• Nếu kí tự đầu tiên là dấu cách thì thực hiện xóa nó đi
• Nếu kí tự cuối cùng là dấu cách thì thực hiện xóa nó đi
if S[length(S)]=' ' then delete(S,length(s),1);
write('xau S sau khi chuan hoa la: ',S);
Dữ liệu vào
- File INPUT1.TXT chứa đoạn văn bản sau:
Nam moi sap den roi, ban co zui khong?
Chuc cac ban don mot cai Tet that vui ve va hanh phuc
Chuc ban luon hoc gioi!
- File INPUT2.TXT chứa các dòng sau:
Trang 18ban em
zui vui
Dữ liệu ra
File KQ.OUT sẽ chứa đoạn văn bản sau:
Nam moi sap den roi, em co vui khong?
Chuc cac em don mot cai Tet that vui ve va hanh phuc
Chuc em luon hoc gioi!
Trang 19Cho một xâu S = ’123456789’ hãy tìm cách chèn vào S các dấu '+' hoặc '-'
để thu được số M cho trước (nếu có thể) Số M nguyên được nhập từ bàn phím.Trong file Output Chenxau.Out ghi tất cả các phương án chèn (nếu có) và ghi
"Khong co" nếu như không thể thu được M từ cách làm trên
Trang 20delete(s,i,length(s)-i+1);
If s[i]='+' then tinh:=t+tinh(s);
If s[i]='-' then tinh:=tinh(s)-t;
If i<9 then try(i+1);
if i=9 then Kiem_tra(i);
Bài 2 Biến đổi xâu
Cho trước một xâu nhị phân có độ dài bất kỳ Cần biến đổi xâu nhị phân này về dạng toàn số 0 Các phép biến đổi chỉ có thể là một trong các loại sau:
- Biến đổi xâu con 11 thành 00
- Biến đổi xâu con 010 thành 000
Hãy chỉ ra một cách biến đổi xâu đã cho thành xâu có toàn 0
Dữ liệu vào: từ file XAUNP.INP xâu nhị phân độ dài bất kỳ
Kết quả: ghi ra file XAUNP.OUT như sau:
- Dòng đầu tiên chứa xâu ban đầu
- Sau đó mỗi dòng là một xâu tiếp theo sau một phép biến đổi Xâu cuối cùng là xâu toàn 0
- Nếu không biến đổi được thì ghi "Khong the bien doi duoc"
Ví dụ:
Trang 2111010011 11010011
110100000001000000000000
10101101 Khong the bien doi duoc
Bài 3 Chuẩn hoá văn bản
Một văn bản được gọi là văn bản chuẩn nếu:
- Hai từ liền nhau có duy nhất một dấu cách trống
- Dấu ngắt câu (dấu chấm, dấu phẩy, dấu chấm phẩy, dấu chấm hỏi, dấu chấm than) được đặt sát vào từ ngay trước nó, sau đó mới đến dấu cách trống
- Dấu mở ngoặc đặt sát vào phía bên trái của từ bắt đầu mở ngoặc
- Dấu đóng ngoặc đặt sát bên phải từ cuối cùng được đóng ngoặc
Hãy viết chương trình để kiểm tra và đưa một đoạn văn bản về dạng văn bản chuẩn
Dữ liệu vào: từ file BAI3.INP
Kết quả: ghi ra file BAI3.OUT văn bản đã được chuẩn hoá
- Nhập xâu S chỉ chứa các kí tự La tinh in thường và các kí tự số từ 0 đến 9
- Đếm và đư ra màn hình số lượng kí tự khác nhau trong xâu S
Ý tưởng:
Với mỗi i (i=1,…,length(S)-1), ta thực hiện xóa tất cả kí tự giống S[i] trongxâu S kể từ vị trí i+1 Số kí tự khác nhau trong xâu S chính là độ dài xâu S còn lại.Chương trình:
Trang 22Hãy xác định số lượng các chiến sĩ công an trong mỗi đội
Dữ liệu vào: tệp XAU.INP chứa một xâu kí tự là kết quả của việc ghép kí hiệu đã
gắn cho tất cả chiến sĩ công an tham gia
Dữ liệu ra: tệp XAU.OUT có không quá 26 dòng, mỗi dòng ghi kí hiệu của mỗi
đội và số lượng thành viên trong đội
Ví dụ:
XAU.INP XAU.OUT
b1c1d1
Ý tưởng:
• Khai báo mảng gồm 26 kí tự dùng để đếm số lần xuất hiện mỗi kí tự
Dem: array[‘a’ ’z’] of byte;
• Việc đếm sẽ được thực hiện bằng câu lênh:
For i:= 1 to length(S) do inc (dem[S[i]]);
Chương trình:
Trang 23Bài 1: Liệt kê chữ cái
Cho một văn bản chứa trong một text file Bạn hãy viết chương trình liệt kêcác chữ cái chỉ có mặt trong văn bản đúng một lần theo thứ tự của bảng chữ cái(không phân biệt chữ hoa và chữ thường)
- Dữ liệu vào: file DEM_CHU.INP gồm nhiều dòng chứa các ký tự trong file
- Dữ liệu ra: file DEM_CHU.OUT
Mỗi dòng ghi các ký tự chỉ xuất hiện đúng một lần trong file theo yêu cầu đề ra
Ví dụ:
IOPU
Dạng 5: Xâu con
Câu 1: Sắp xếp xâu.
Trang 24Người ta định nghĩa: Từ là một nhóm ký tự đứng liền nhau.
Cho một xâu S gồm các ký tự lấy từ tập ‘a’ ‘z’ và dấu cách Xâu không quá 20
từ, mỗi từ dài không quá 10 ký tự
Yêu cầu: Sắp xếp các từ của xâu ký tự theo thứ tự không giảm của độ dài các từ
trong xâu St
Dữ liệu vào: Cho trong file văn bản SAPXAU.INP, có cấu trúc:
- Dòng 1: Ghi một xâu ký tự St (có ít nhất 1 từ)
Dữ liệu ra: Ghi ra file văn bản SAPXAU.OUT, theo cấu trúc:
- Dòng 1: Ghi các từ của xâu ký tự sau khi được sắp xếp Các từ được ghi cách
- Thực hiện chuẩn hóa xâu S
- Dùng 1 mảng không quá 20 phần tử, mỗi phần tử là một xâu kí tự để chứa các từ trong xâu
- Sắp xếp các phần tử mảng theo độ dài của các phần tử
Trang 25(Đề thi chọn học sinh giỏi tỉnh lớp 11 – Năm học 2011-2012)
Xâu S chỉ bao gồm các kí tự ngoặc mở “(“ và ngoặc đóng “)” Xâu S xácđịnh một cách đặt ngoặc đúng nếu thỏa mãn các điều kiện sau:
Yêu cầu: Hãy xác định đoạn ngoặc đúng dài nhất
Dữ liệu vào là tệp văn bản NGOAC.INP chứa một dòng không quá 255 dấu ngoặc
Dữ liệu ra là tệp văn bản NGOAC.OUT:
- Dòng đầu tiên ghi độ dài của dãy ngoặc đúng dài nhất
- Dòng thứ hai ghi chỉ số đầu và chỉ số cuối của đoạn ngoặc đúng đó
- Nếu không có đoạn ngoặc đúng nào thì ghi vào tệp thông báo “Khong co”