Kiểu dữ liệu xâu trong Pascal với việc sử dụng kiểu ansistring trong trình biên dịch Free Pascal giúp giải quyết một vài bài toán trong các kì thi học sinh giỏi tỉnh Vĩnh Phúc liên quan đến kiểu xâu. Kết hợp các bài toán liên quan đến kiểu tập hợp và kiểu đồ thị (cây nhị phân đơn giản).
Trang 1DANH MỤC CÁC TỪ VIẾT TẮT 2
PHẦN I MỞ ĐẦU 3
1.1 Lý do chọn đề tài 3
1.1.1 Cơ sở lí luận 3
1.1.2 Cơ sở thực tiễn 3
1.2 Định hướng nghiên cứu 3
1.2.1 Mục đích nghiên cứu 3
1.2.2 Đối tượng nghiên cứu 4
1.2.3 Phạm vi nghiên cứu 4
1.2.4 Phạm vi ứng dụng 4
1.2.5 Phương pháp nghiên cứu 4
PHẦN II NỘI DUNG 5
2.1 Cơ sở lý thuyết 5
2.1.1 Kiểu dữ liệu xâu 5
2.1.2 Kiểu dữ liệu xâu trong TP và FP 6
2.1.2.1 Kiểu dữ liệu xâu trong TP 6
2.1.2.2 Kiểu dữ liệu xâu trong FP 6
2.2 Một số câu hỏi chọn lọc liên quan đến kiểu dữ liệu xâu trong các đề thi HS giỏi tỉnh Vĩnh Phúc những năm gần đây 7
2.3 Một số lưu ý 20
PHẦN III KẾT LUẬN VÀ KIẾN NGHỊ 21
3.1 Kết luận 21
3.2 Kiến nghị 21
NHẬN XÉT CỦA TỔ CHUYÊN MÔN VÀ HỘI ĐỒNG CHẤM 22
PHỤ LỤC CÂU HỎI 23
DANH MỤC TÀI LIỆU THAM KHẢO 24
Trang 3PHẦN I MỞ ĐẦU
1 Lý do chọn đề tài
1.1.1 Cơ sở lí luận
Trong thời đại thông tin bùng nổ ngày nay, việc lập được các chương trình
tự hoạt động cho máy tính, máy gia dụng là cần thiết Và để làm được việc đócần có một quá trình nghiên cứu, học tập về ngôn ngữ lập trình lâu dài, qua đónhà lập trình có thể chọn một ngôn ngữ lập trình thích hợp Tuy nhiên mọi thứđiều có điểm khởi đầu của nó, với HS việc học Pascal là khởi đầu cho việc tiếpcận ngôn ngữ lập trình bậc cao, qua đó giúp các em hình dung được sự ra đời,cấu tạo, hoạt động cũng như ích lợi của các chương trình hoạt động trong máytính, các máy tự động…Từ đó giúp các em có thêm một định hướng, một niềmđam mê về tin học, về nghề nghiệp mà các em chọn sau này Đồng thời Pascal làmột ngôn ngữ có cấu trúc thể hiện trên 3 yếu tố: Cấu trúc về mặt dữ liệu, cấutrúc về mặt lệnh, cấu trúc về mặt chương trình
Mỗi ngôn ngữ đều cung cấp cho chúng ta rất nhiều kiểu dữ liệu khác nhaunhư: kiểu số nguyên, kiểu số thực, kiểu kí tự, kiểu logic, kiểu mảng, kiểu bảnghi, kiểu xâu, kiểu tệp,…để có thể giải quyết nhiều dạng bài toán khác nhau.Trong đó, kiểu xâu là một kiểu dữ liệu đặc biệt do nó có thể biến đổi qua lại mộtcách linh hoạt bằng cách sử dụng các hàm, các phép toán trên xâu kí tự, đôi khicác kiểu dữ liệu khác cũng có thể biến đổi thành kiểu xâu để xử lý một cách dễdạng hơn (cộng, nhân, chia, chia lấy nguyên, chia lấy dư,… các số lớn,…)
1.1.2 Cơ sở thực tiễn
Qua hơn ba năm dạy đội tuyển HS giỏi tin học, hơn hai năm dạy chươngtrình chính khóa tin học lớp 11 Tôi nhận thấy kiểu dữ liệu xâu là một phần haynhưng không phải dễ Từ những kinh nghiệm mà tôi có được, cùng quá trình tìmhiểu về xâu trong Pascal tôi nhận thấy kiến thức về xâu rất rộng Mặc dù kiếnthức về xâu của bản thân tôi còn nhiều hạn chế nhưng sau một thời gian tìm hiểu
về kiểu dữ liệu xâu kí tự tôi rất muốn viết ra những kiến thức mà tôi đã lĩnh hộiđược, muốn đưa ra những chương trình về xâu mà tôi cảm thấy tâm đắc nhất cóthể giúp cho các em HS, đặc biệt là những HS trong đội tuyển HS giỏi và những
GV mới ra trường đang bồi dưỡng đội tuyển có được những kiến thức bổ trợ choquá trình giảng dạy và học tập của mình Từ những lý do trên tôi viết đề tài:
“Kiểu dữ liệu xâu và thuật toán một số bài tập về xâu trong kì thi chọn HS giỏitin học THPT những năm gần đây”
2 Định hướng nghiên cứu
1.1.3 Mục đích nghiên cứu
- Cải thiện kiến thức của bản thân về kiểu dữ liệu xâu trong ngôn ngữ lậptrình Pascal
Trang 4- Giúp các GV mới tham gia bồi dưỡng HS giỏi tin học, các HS tham giavào các đội tuyển tin học trong các trường và các HS có niềm đam mê vớimôn lập trình Pascal có một tài liệu để tham khảo trong quá trình giảngdạy và học tập của mình.
1.1.4 Đối tượng nghiên cứu
Xâu dữ liệu trong ngôn ngữ lập trình Pascal dựa trên một số bài tập liênquan đến kiểu xâu trong các đề thi HS giỏi tin học THPT tỉnh Vĩnh Phúc nhữngnăm gần đây
1.1.5 Phạm vi nghiên cứu
- Kiến thức: Kiểu dữ liệu xâu trong ngôn ngữ lập trình Pascal
- Thời gian: từ 02/01/2012 – đến nay
1.1.6 Phạm vi ứng dụng
Tài liệu này có thể sử dụng để GV và HS đọc tham khảo
- Đối với HS: Giúp HS hiểu hơn và tham khảo về hướng giải quyết một vàidạng bài tập kiểu dữ liệu xâu trong các đề thi HS giỏi gần đây
- Đối với GV: Đây là một tài liệu tham khảo cho các GV THPT khi dạy HSgiỏi cũng như các GV dạy trên lớp
1.1.7 Phương pháp nghiên cứu
- Nghiên cứu về lí luận dạy học, quá trình dạy học
- Nghiên cứu chương trình, thuật toán
- Tổng kết kinh nghiệm
Trang 5PHẦN II NỘI DUNG
3 Cơ sở lý thuyết
2.1.1 Kiểu dữ liệu xâu
a) Khái niệm xâu
- Xâu là dãy các kí tự trong bộ 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 một xâu được gọi là độ dài của xâu Xâu
có độ dài bằng 0 gọi là xâu rỗng
- Các ngôn ngữ lập trình đều có quy tắc, cách thức cho phép xác định:
o Tên kiểu xâu
o Cách khai báo biến kiểu xâu
o Số lượng các kí tự của xâu
o Các phép toán thao tác với xâu
o Cách tham chiếu tới phần tử của xâu
- Tham chiếu tới phần tử trong xâu được xác định thông qua chỉ số củaphần tử trong xâu
- Chỉ số phần tử trong xâu thường được đánh số là 1
- Trong ngôn ngữ Pacal, tham chiếu tới phần tử thường được viết:
<Tên biến xâu>[chỉ số] Ví dụ: s= ‘abcde’ s[2]= ‘b’
b) Khai báo xâu
Var <tên các biến xâu>:<kiểu dữ liệu xâu>;
Trong đó:
- Tên các biến xâu là các biến xâu được đặt tên theo đúng quy tắc đặt tên
- Kiểu dữ liệu xâu có thể tùy thuộc vào sử dụng ngôn ngữ lập trình TP vàFP:
o Trong TP: String;
o Trong FP: asistring, shortstring, string…
c) Các thao tác xử lý xâu
- Phép ghép xâu: sử dụng dấu cộng (+) để ghép nhiều xâu thành một xâu
Có thể thực hiện phép ghép xâu với hằng và biến xâu
Ví dụ: ‘Lap Thach’ + ‘ ‘ + ‘Vinh Phuc’= ‘Lap Thach Vinh Phuc’
- Phép so sánh xâu: bằng (=), khác (<>), nhỏ hơn (<), lớn hơn (>), nhỏ hơnhoặc bằng (<=), lớn hơn hoặc bằng (>=) có thứ tự ưu tiên thực hiện thấphơn phép ghép xâu và thực hiện việc so sánh hai xâu theo quy tắc sau:
o Xâu A lớn hơn xâu B nếu kí tự đầu tiên khác nhau giữa chúng kể từtrái sang trong xâu A có mã ASCII lớn hơn
Ví dụ: ‘May tinh cua toi’ < ‘may tinh cua toi’
Trang 6o Nếu A và B là các xâu có độ dài khác nhau và A là đoạn đầu của Bthì A nhỏ hơn B
Ví dụ: ‘May tinh’ < ‘May tinh cua toi’
o Hai xâu được coi là bằng nhau nếu như chúng giống nhau hoàntoàn:
Ví dụ: ‘TIN HOC’ = ‘TIN HOC’
d) Các hàm và thủ tục xử lý xâu, kí tự (Đây cũng là một trong các lý do tại
sao không xử dụng mảng các kí tự để khai báo cho xâu mặc dù cách thứctruy cập tới phần tử của xâu và mảng tương tự nhau – Nếu sử dụng mảngthì ta sẽ không áp dụng được các hàm và thủ tục rất tiện lợi này)
Một số thủ tục chuẩn:
Delete(St, vt, n): xóa n kí tự của xâu St bắt đầu từ vị trí vt.
Insert(S1, S2, vt): chèn sâu S1 vào S2 bắt đầu từ vị trí vt của S2
Val(St, x, m): Đổi giá trị xâu St thành số ghi giá trị vào biến X, nếu không
đổi được thì vị trí gây lỗi ghi trong m, nếu đổi thành công thì m = 0
Str(X, St): chuyển số X thành xâu kí tự lưu trong St.
Một số hàm chuẩn:
Copy(St, vt, n): sao chép từ xâu St, n kí tự bắt đầu từ vị trí vt.
Pos(S1, S2): tìm vị trí xuất hiện đầu tiên của S1 trong S2.
Length(St): cho độ dài xâu St.
Upcase(ch): cho chữ cái viết hoa tương ứng với chữ trong ch.
Chr(X): cho kí tự có mã X trong bảng mã ASCII.
Ord(ch): cho mã của kí tự ch trong bảng mã.
Concat(St1,St2, StN): Hàm ghép nối các xâu St1,St2, StN thành xâu ký
tự theo thứ tự đã viết Các viết này tương tự như: ST := St1 + St2 + +StN
2.1.2 Kiểu dữ liệu xâu trong TP và FP
2.1.2.1 Kiểu dữ liệu xâu trong TP
Trong TP xâu chỉ có độ dài không quá 255 kí tự nên nếu như với bài toán
có độ dài lớn hơn thì việc sử dụng kiểu xâu trong TP gặp khó khăn hơn rất nhiều
do vậy lựa chọn tốt hơn khi bạn vẫn muốn lập trình bằng ngôn ngữ Pascal đó là
sử dụng trình biên dịch FP Đối với TP kiểu dữ liệu xâu thường dùng là Stringchỉ có độ dài tối đa 255 kí tự Nhưng hầu hết các bài toán trong các đề thi họcsinh giỏi có độ dài xâu lớn hơn rất nhiều nên việc xử lý sẽ gặp rất nhiều khókhăn Do vậy, ta phải dùng tới trình biên dịch FP
2.1.2.2 Kiểu dữ liệu xâu trong FP
Khi lập trình, chúng ta rất nhiều lần gặp vấn đề với các xâu tối đa 255 kí tựcủa TP (chẳng hạn bài toán xâu đối xứng, bài toán đếm từ…) Ta có thể giải
Trang 7quyết vấn đề bằng mảng kí tự (array of char) nhưng khi đó ta lại không thể dùngcác phép toán trên xâu rất mạnh của Pascal.
Không chỉ có cải tiến về kiểu nguyên, kiểu string trong FP cũng được cảitiến rất tốt Kiểu xâu kí tự trong FP không còn hạn chế 255 kí tự của TP nữa mà
có kích thước tối đa là khoảng 2 tỉ kí tự Hơn nữa FP còn hỗ trợ kiểu xâuUnicode (WideString) Nếu bạn vẫn muốn sử dụng kiểu String cũ của TP, bạn cóthể dùng kiểu ShortString hoặc String
Trong môi trường Windows, trình biên dịch FP có nhiều ưu thế hơn do tínhtương thích và hỗ trợ bộ nhớ lớn hơn
Các kiểu dữ liệu xâu kí tự thường sử dụng trong FP: String, ShortString,AnsiString, WideString
4 Một số câu hỏi chọn lọc liên quan đến kiểu dữ liệu xâu trong các đề
thi HS giỏi tỉnh Vĩnh Phúc những năm gần đây
Câu 1 (Bài 2 – Kì thi chọn HSG lớp 12 THPT – Năm học: 2014 – 2015)
Keyboard: Harry – người bạn của chúng ta đang gõ một đoạn văn bản bằng mộtbàn phím đặc biệt với các ký tự được sắp xếp theo cách như sau:
Chúng ta đã có một dãy các ký tự mà Harry đã gõ vào, giờ cần tìm lại chuỗinguyên bản ban đầu
Kết quả: in ra một dòng chứa chuỗi kí tự nguyên bản
Trang 8Thuật toán:
Bước 1 Đọc ch1 tương ứng là kiểu kí tự lưu kí tự “L” hoặc “R”
Bước 2 Trong khi chưa kết thúc tệp ta tiếp tục thực hiện
Trang 9Câu 2 (Bài 3 – Kì thi chọn HSG lớp 10 THPT – Năm học: 2013 – 2014)
Cho bảng kích thước được chia thành lưới ô vuông đơn vị Các hàngđược đánh số từ theo chiều từ trên xuống dưới Các cột được đánh số từ
theo chiều từ trái qua phải Ô nằm trên giao của hàng và cột đượcgọi là ô và trên đó ghi ký tự , kí tự này là chữ cái latin in hoa hoặc dấu #.Mỗi từ trong bảng là một dãy liên tiếp các chữ cái trên cùng một hàng (tính từtrái qua phải) hoặc một dãy liên tiếp các kí tự trên cùng một cột (tính từ trênxuống dưới) sao cho hai từ liên tiếp trên cùng một hàng hoặc trên cùng một cộtcách nhau ít nhất bởi một dấu # Yêu cầu: Tìm từ lớn nhất theo thứ tự từ điển
Dữ liệu:
Dòng Hai số nguyên dương cách nhau ít nhất một dấu cách
Dòng : Dòng thứ ghi ký tự liền nhau, kí tự thứ là
Kết quả: Ghi ra từ lớn nhất theo thứ tự từ điển
Các bước xây dựng thuật toán:
Trang 10Lưu ý về việc sử dụng các biến s, max kiểu ansistring; ch kiểu char để đọc từng
kí tự trong xâu Sử dụng thêm mảng xâu a kiểu ansistring có tối đa 1000 kí tự.Bước 1 Đọc n, m {m tương ứng là số cột, n tương ứng là số hàng)
Bước 2 {Ta sẽ đọc dữ liệu và xử lý dữ liệu theo hàng ngang trước Sau khi kếtthúc quá trình xử lý này ta sẽ thu được xâu lớn nhất theo hàng ngang của mảng
o B2.2.4 Tăng j lên 1 đơn vị
o B2.2.5 Kiểm tra nếu j>m thì sử dụng lệnh xuống dòng ở tệp f đểxuống đầu dòng tiếp theo đọc dữ liệu và kiểm tra nếu max<s thìmax:=s, s:=’’và chuyển sang B2.3 Nếu j<=m thì quay trở lạiB2.2.1
- B2.3 Tăng i và quay lại B2.2
- B2.4 Thực hiện đóng tệp f (close(f)) mở tệp để đọc reset(f) để bắt đầuđọc lại dữ liệu theo hàng dọc, nhưng trước đó phải sử dụng lệnh readln(f)
để bỏ qua dòng đầu tiên chứa 2 số n và m
Bước 3 {Đọc dữ liệu và xử lý dữ liệu theo hàng dọc, với việc xử lý theo hàngdọc sẽ tốn thời gian hơn một chút}
- B3.1 Khởi tạo mảng a[i] có i chạy từ 1 đến m là rỗng
o B3.3.4 Tăng I lên 1 đơn vị
o B3.3.5 Nếu i>m thì sử dụng lệnh readln(f) đưa con trỏ tệp xuốngđầu dòng tiếp theo còn i<=m thì quay lại B3.3.1
- B3.4 Tăng j lên 1 đơn vị
Trang 11- B3.5 Kiểm tra nếu j>n thì thực hiện cho biến k chạy từ 1 đến m nếua[k]>max thì gán max:=a[k] và chuyển sang Bước 4 còn không thì quaytrở lại B3.3.
Bước 4 Đưa ra max và kết thúc
{Tim xau max theo hang doc}
close(f); reset(f);readln(f); {Mo lai tu dau tep va xuong 1 dong}
for i:=1 to m do a[i]:='';
Trang 12begin
read(f,ch);
if (ch='#')and(a[i]<>'') then begin
if max<a[i] then max:=a[i];a[i]:='';
end;
if ch<>'#' then a[i]:=a[i]+ch;
inc(i);
if i>m then readln(f);
end; inc(j); if j>n then
Câu 3 (Bài 2 – Kì thi chọn HSG lớp 10 THPT – Năm học: 2012 – 2013)
Xâu moo: S[0]:='moo';
Với xâu k>=0, s[k+1]:=s[k]+'mo '+s[k] trong đó 'mo ' gồm k+3 kí tự 'o'Chẳng hạn:
B4.2 Trong khi j<n thực hiện
Tăng k lên 1 đơn vị; st:=st+’o’; s2:=s1; s1:=s2+st+s2; j:=length(s1)
B4.3 Nếu j=n thì kí tự cần tìm là ‘o’ còn ngược lại: d1:=length(s1)
Trong khi j>n thực hiện: giảm j, giảm d1
Kết quả s1[d1]
Trang 13if n>1000000000 then write('o') else
if n<=3 then write(s1[n]) else
Câu 4 (Bài 3 – Kì thi chọn HSG lớp 12 THPT – Năm học: 2012 – 2013)
(Tương tự Bài 2 – Kì thi chọn HSG lớp 10 THPT – Năm học: 2010 – 2011)
Số đẹp Theo quan niệm của khoa học huyền bí phương Đông, số 6 đượccoi là LỘC, số 8 được coi là PHÁT Nhiều người cố gắng sở hữu các số này để
sử dụng cho số điện thoại, biển số xe,… Số đẹp là số trong biểu diễn thập phânchỉ chứa 2 số trên Dãy các số đẹp theo thứ tự là: 6, 8, 66, 68, 86, 88,…
Yêu cầu: tìm số đẹp thứ k (1≤k≤109)
Hướng dẫn thuật toán: với bài tập dạng này các bạn hãy vẽ dạng cây đồ thì vớibên trái là số nhỏ hơn, bên phải là số lớn hơn rồi lần lượt đánh trọng số từ 1, 2,
… Sau đó các bạn sẽ hiểu quy luật dựa vào code sau:
var k:int64; s:ansistring;
begin
readln(k); {Nhap du lieu}
s:='';
Trang 14Dữ liệu: cho trong file văn bản NUMMAX.INP
- Dòng đấu: ghi hai số nguyên N và K, cách nhau bởi một dấu cách
- Dòng thứ hai: ghi xâu S gồm N chữ số, chữ số đầu tiên luôn khác 0
Kết quả: ghi ra file văn bản NUMMAX.OUT kết quả tìm được trên một dòngduy nhất
Bước 1 M:=n-k với m là số chữ số cần giữ lại
W:=’’ với w là xâu sau khi đã gạch bỏ đi k chữ số; vt:=1;
Bước 2 Trong khi length(w)<m thì tiếp tục thực hiện B2.1 còn không chuyểnsang Bước 3
B2.1 max:=s[vt] trong đó s là xâu ban đầu; vt1:=vt
B2.2 Xét từ vị trí vt tới vị trị n-(m-length(w))+1 của xâu s length(w))+1 Nếu max<s[j] thì gán max:=s[j] và vt1:=j
(j=vtn-(m-B2.3 w:=w+max; vt:=vt1+1 rồi quay lại Bước 2
Trang 15Bước 3 Đưa ra xâu w
m:=n-k; {So chu so can giu lai}
w:=''; {xau can tim} vt:=1;
Câu 6 (Bài 3 – Kì thi chọn HSG lớp 10 THPT – Năm học: 2010 – 2011)
Xâu con đối xứng:
Với mỗi xâu T, ta kí hiệu Tr là xâu nhận được từ T bằng cách viết T theo chiều từphải qua trái, chẳng hạn (abc)r = cba Mỗi xâu T được gọi là xâu đối xứng nếu T
= Tr, chẳng hạn abccba, xyzyx là các xâu đối xứng
Cho xâu S, xác định độ dài xâu con đối xứng dài nhất của S
Dữ liệu (spalin.inp): Chứa xâu S, độ dài không vượt quá 1000, chỉ gồm các chữcái latin a z, A Z
Kết quả (spalin.out): số nguyên là độ dài xâu con đối xứng dài nhất của S
Ví dụ:
Thuật toán:
Trang 16Bước 1 Viết hàm đối xứng có kiểu trả về là true nếu xâu đối xứng còn trả vềfalse nếu xâu không là xâu đối xứng
Bước 2 Kiểm tra xâu s đối xứng thì kết quả là length(s) còn ngược lại chuyểnsang bước 3
Bước 3 Gán d:=length(s)-1 {Sử dụng d để kiểm tra từ xâu có độ dài lớn hơn tớixâu có độ dài nhỏ dần}
Bước 4 Trong khi d>0 thì thực hiện
B4.1 Cho I chạy từ 1 tới length(s)-d+1 thì thực hiện:
Var g, f:text;d, max, i:word; s, st:ansistring;
{Ham kiem tra tinh doi xung cua mot xau}