Tải bản đầy đủ (.doc) (21 trang)

Một số phương pháp rèn luyện tư duy lập trình pascal cho học sinh qua các dạng bài tập kiểu xâu

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 (138.46 KB, 21 trang )

SỞ GIÁO DỤC VÀ ĐÀO TẠO THANH HÓA

TRƯỜNG THPT TRẦN PHÚ NGA SƠN
------------***------------

SÁNG KIẾN KINH NGHIỆM

MỘT SỐ PHƯƠNG PHÁP RÈN LUYỆN TƯ DUY LẬP
TRÌNH PASCAL CHO HỌC SINH QUA CÁC DẠNG
BÀI TẬP KIỂU XÂU

Họ và tên:
Phạm Thị Nhung
Chức vụ:
Giáo viên
SKKN thuộc bộ môn: Tin học

THANH HÓA NĂM 2017


MỤC LỤC
1. MỞ ĐẦU............................................................................................. 1
1.1. LÍ DO CHỌN ĐỀ TÀI...........................................................................1
1.2. MỤC ĐÍCH NGHIÊN CỨU..................................................................2
1.3. ĐỐI TƯỢNG NGHIÊN CỨU................................................................2
1.4. PHƯƠNG PHÁP NGHIÊN CỨU..........................................................3

2. NỘI DUNG SÁNG KIẾN KINH NGHIỆM.........................................3
2.1. CƠ SỞ LÝ LUẬN CỦA SÁNG KIẾN KINH NGHIỆM.......................3
2.2. THỰC TRẠNG CỦA VẤN ĐỀ.............................................................3
2.3. CÁC GIẢI PHÁP ĐÃ SỬ DỤNG ĐỂ GIẢI QUYẾT VẤN ĐỀ............4


2.3.1. Chính xác hóa nhận thức của học sinh về “Kiểu xâu”........................................4
2.3.2. Khắc phục sai lầm của học sinh trong lập trình kiểu xâu...................................7
2.3.3. Rèn luyện kỹ năng cho học sinh qua một số bài tập đặc trưng...........................8

2.4. HIỆU QUẢ CỦA SÁNG KIẾN KINH NGHIỆM................................18

3. KẾT LUẬN VÀ KIẾN NGHỊ............................................................19

1. MỞ ĐẦU
1.1. LÍ DO CHỌN ĐỀ TÀI
Cùng với quá trình Tin học hóa trên nhiều lĩnh vực hoạt động của xã hội loài
người và đem lại nhiều hiệu quả to lớn thì việc đưa bộ môn Tin học vào giảng dạy
trong các trường trung học phổ thông cũng được đẩy mạnh và không kém tầm quan
1


trọng. Môn Tin học đã được đưa vào giảng dạy ở trường phổ thông như những môn
học khác bắt đầu từ năm 2006-2007.
Nhận thức được tầm quan trọng, sự ảnh hưởng to lớn của bộ môn Tin học nói
riêng và của lĩnh vực công nghệ thông tin nói chung đối với các lĩnh vực khác cũng
như sự phát triển của xã hội. Tôi nghĩ bản thân là một giáo viên dạy môn Tin học
phải có trách nhiệm làm sao cho học sinh hiểu và yêu thích bộ môn này, tạo cho học
sinh sự hứng khởi, niềm đam mê học hỏi, sáng tạo để phát triển ngành Tin học ngày
càng cao hơn, xa hơn, mang lại nhiều ứng dụng thiết thực.
Trong quá trình giảng dạy, tôi nghĩ không phải cứ tìm được nhiều bài toán
khó, bài toán hay để giảng dạy cho học sinh. Mà vấn đề đặt ra là chúng ta cần phải
tích cực tìm tòi, sáng tạo trong việc đưa ra cách giải quyết những bài toán đó để
giúp cho học sinh có sự hứng thú, tìm tòi sáng tạo trong quá trình giải quyết học
tập, từ đó biết vận dụng linh hoạt trong các tình huống cụ thể ngoài thực tế.
Để thực hiện được điều đó, theo tôi chúng ta cần phải tìm tòi, nghiên cứu tìm

ra những bài toán phù hợp, kích thích được sự độc lập, tích cực của học sinh trong
học tập. Trên cơ sở đó, học sinh có thể tự mình tìm ra được những ý tưởng sáng tạo
vận dụng thiết thực vào cuộc sống thực tế khi nhu cầu nảy sinh, khi đó các em có
thể tự mình hoàn thành được ý tưởng đó.
Trong các vấn đề về Tin học được đưa vào giảng dạy ở chương trình bậc học
phổ thông hiện nay. Khi nói đến vấn đề dạy học lập trình pascal cho học sinh, các
kiểu dữ liệu chuẩn không đủ biểu diễn dữ liệu của các bài toán trong thực tế. Các
ngôn ngữ lập trình có quy tắc, cách thức cho phép người lập trình xây dựng những
kiểu dữ liệu phức tạp từ những kiểu đã có. Một trong số đó là kiểu xâu là kiểu dữ
liệu có cấu trúc, dữ liệu kiểu phi số - dạng kí tự; Là kiểu dữ liệu không kém phần
quan trọng trong lập trình Pascal.
Vấn đề đặt ra là: Dạy học sinh kiểu xâu như thế nào để đạt hiệu quả? Đó
chính là lí do tôi quyết định chọn đề tài: “Một số phương pháp rèn luyện tư duy
lập trình Pascal cho học sinh qua các dạng bài tập kiểu xâu”.

1.2. MỤC ĐÍCH NGHIÊN CỨU
- Giúp học sinh có cái nhìn đúng đắn hơn về lập trình và tự tin hơn, chủ động
hơn khi giải các bài tập kiểu xâu một cách hiệu quả để hoàn thành chương trình một
cách tốt nhất.

1.3. ĐỐI TƯỢNG NGHIÊN CỨU
- Học sinh khối 11 Trường THPT Trần Phú và đặc biệt là các đối tượng học
sinh ôn luyện học sinh giỏi.
2


1.4. PHƯƠNG PHÁP NGHIÊN CỨU
- Thực tiễn giảng dạy học sinh khối 11;
- Tham khảo SGK, SGV Tin học 11 và tài liệu về ngôn ngữ lập trình Pascal;


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
Bản thân là một giáo viên giảng dạy môn Tin học tại trường THPT Trần Phú,
Với chất lượng học sinh đầu vào thấp, khi dạy học sinh về lập trình Pascal, đặc biệt
là các bài toán “Kiểu xâu”, nếu chỉ truyền thụ kiến thức một cách đơn thuần thì
phần đông các em sẽ không nắm rõ kiến thức cơ bản về “Kiểu xâu”, cách sử dụng
kiểu xâu và nhất là khả năng vận dụng linh hoạt các bài toán “Kiểu xâu” vào thực
tiễn. Đa số các em chỉ hiểu một cách thụ động và không có tính tư duy, sáng tạo
trong việc xây dựng và hình thành thuật toán cho từng bài toán cụ thể. dẫn đến
những sai lầm trong lập trình. Khi trình bày vấn đề này cho học sinh, tôi đã thực
hiện như sau:
Trước hết, tôi nhắc lại một số điểm quan trọng trong kiểu xâu; sau đó chỉ ra
những sai lầm mà các em hay mắc phải trong một số dạng bài tập. Đồng thời đưa ra
cách khắc phục những sai lầm đó. Chỉ ra các cách tiếp cận khác nhau đối với từng
bài toán cụ thể để nâng cao khả năng tư duy cho các em. Sau cùng cho các em một
số bài tập tự rèn luyện kỹ năng. Đặc biệt, là các bài toán “Kiểu xâu” ứng dụng để
giải quyết các vấn đề trong thực tiễn. Làm như vậy tôi thấy có hiệu quả. Học sinh
hiểu rõ được về bản chất của từng bài toán cụ thể, các em dễ dàng tiếp cận được
những yêu cầu khó khăn hơn trong các bài toán khác nhau. Đó chính là những căn
cứ để tôi viết đề tài này.

2.2. THỰC TRẠNG CỦA VẤN ĐỀ
Thực tế vẫn còn số đông giáo viên chưa từ bỏ được kiểu dạy học truyền
thống đó là giáo viên chỉ biết say sưa truyền thụ kiến thức, còn học sinh thì tiếp thu
bài học một cách rất thụ động, mô tuýp. Và phần lớn học sinh vẫn theo lối mòn từ
xưa chờ đợi vào kiến thức sẵn có mà giáo viên đưa ra để từ đó sử dụng làm bài tập
như một công thức. Hầu hết các em không biết vận dụng linh hoạt các kiến thức
tổng hợp để giải quyết các bài toán một cách chủ động, sáng tạo.
Đứng trước thực trạng như vậy, tôi thiết nghĩ phải làm thế nào để trong việc
giảng dạy cho học sinh, ngoài việc giúp học sinh lĩnh hội những kiến thức cơ bản,

người thầy còn phải biết kích thích tính tích cực, sự sáng tạo say mê học hỏi của học
sinh trong việc học tập, đòi hỏi học sinh phải có ý thức về những mục tiêu đặt ra và
tạo được động lực bên trong thúc đẩy bản thân họ hoạt động để đạt các mục tiêu đó.
Trên cơ sở những kiến thức mà học sinh được học về lập trình để viết
chương trình bằng ngôn ngữ lập trình Pascal, học sinh có thể chủ động vận dụng
kiến thức về “Kiểu xâu” để giải quyết bài toán trong thực tế. Bởi vì, ngôn ngữ
Pascal có tính cấu trúc mạnh, có cơ sở và nó đòi hỏi chương trình phải chặt chẽ,
3


logic. Đặc biệt, khi được trang bị kiến thức vững vàng học sinh có thể có kỹ năng
viết chương trình tốt hơn, nhìn nhận vấn đề một cách sáng sủa hơn, chặt chẽ hơn và
nhất là xây dựng được thuật toán tối ưu có thể giúp cho các em hoàn thành những
chương trình lớn hơn vượt ra những bài toán bình thường mà nội bộ môn học đòi
hỏi. Chính vì vậy, bản thân tôi cần phải nỗ lực tìm tòi, sáng tạo giúp cho học sinh
nhìn nhận vấn đề một cách tích cực hơn, sáng tạo hơn và nhất là giúp cho các em có
thể yêu thích nhiều hơn nữa ngôn ngữ lập trình Pascal thông qua các bài toán cụ thể.

2.3. CÁC GIẢI PHÁP ĐÃ SỬ DỤNG ĐỂ GIẢI QUYẾT VẤN ĐỀ
Bằng những kiến thức về Tin học và những kinh nghiệm của bản thân trong
công tác giảng dạy bộ môn Tin học, để phát triển khả năng tư duy sáng tạo cho học
sinh trong quá trình viết chương trình tôi đã sử dụng phương pháp gợi động cơ kích
thích tính tích cực, khả năng tư duy, sự sáng tạo, say mê, tìm tòi, học hỏi của học
sinh qua cách giảng dạy thực tiễn về “Kiểu xâu”, được trình bày qua các giải pháp
dưới đây:
- Chính xác hóa nhận thức của học sinh về “Kiểu xâu”;
- Khắc phục sai lầm của học sinh trong lập trình kiểu xâu;
-Rèn luyện kỹ năng cho học sinh qua một số bài tập đặc trưng;
Để thực hiện được ý tưởng đã nêu trong đề tài, tôi đã áp dụng các giải pháp
trên chủ yếu vào giảng dạy học sinh khối 11 và làm nền tảng ôn luyện học sinh giỏi.

Tôi đã đưa ra các ví dụ từ dễ đến khó, từ đơn giản đến phức tạp tương ứng với từng
giải pháp và hướng dẫn học sinh xác định được trọng tâm bài toán. Sau đó tôi cùng
với học sinh hoàn thiện bằng cách gợi ý và chỉ ra những vấn đề nảy sinh cụ thể
trong yêu cầu của bài toán. Tôi đã tổ chức thực hiện các giải pháp như sau:

2.3.1. Chính xác hóa nhận thức của học sinh về “Kiểu xâu”
2.3.1.1. Có thể xem xâu là mảng một chiều mà mỗi phần tử là một kí tự. Các kí
tự của xâu được đánh số thứ tự, thường bắt đầu từ 1;
Xét ví dụ: Cho khai báo sau:
Type Hoten = String[30];
St80 = String[80];
Var Name: Hoten;
Line: St80;
St: String;
Hãy điền từ/cụm từ thích hợp vào các phần còn trống của các phát biểu sau:
a. Hoten và St80 là các……………………
b. Name là…………..có tối đa…………..kí tự.
c. Line là…………….có tối đa…………..kí tự.
d. St là……………….có tối đa…………..kí tự.
Nếu chỉ dạy như sách giáo khoa đã trình bày trong phần khai báo biến xâu.
Sách giáo khoa chỉ đưa ra một cách khai báo trực tiếp. Mặc dù, ta vẫn hiểu “xâu là
4


mảng một chiều”, và cách khai báo biến kiểu xâu cũng tương tự kiểu mảng có hai
cách: khai báo trực tiếp và khai báo gián tiếp. Nhưng sách giáo khoa đã không trình
bày lại, nếu giáo viên không chú ý mà cứ trình bày như sách giáo khoa thì vô hình
dung học sinh sẽ không biết cách khai báo gián tiếp đối với kiểu xâu. Như vậy, với
một bài toán tưởng như đơn giản nhưng học sinh lại rất lúng túng khi xác định
thành phần trong khai báo nêu trong ví dụ 1 trên đây. Vậy nên, trong khi dạy cách

khai báo biến xâu, tôi vẫn trình bày rõ hai cách khai báo cho học sinh.
Cách 1. Khai báo trực tiếp biến xâu:
Var <tên biến xâu>: string[độ dài lớn nhất của xâu];
Var <tên biến xâu>: string; {Khi đó độ dài lớn nhất của xâu sẽ nhận giá trị
ngầm định là 255}.
Ví dụ: Var hoten : string[26];
Var chugiai: string;
Cách 2. Khai báo gián tiếp biến xâu qua kiểu xâu:
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>;
Ví dụ: Type Hoten = String[30];
Var name: Hoten;
Như vậy, học sinh có thể nắm rõ cách khai báo biến xâu, giải quyết ví dụ 1
một cách dễ dàng.
a. Hoten và St80 là các kiểu xâu kí tự.
b. Name là biến kiểu xâu kí tự;có tối đa 30 kí tự.
c. Line là biến kiểu xâu kí tự ;có tối đa 80 kí tự.
d. St là biến kiểu xâu kí tự; có tối đa 255 kí tự.
2.3.1.2. Tuy có thể hình dung xâu như mảng một chiều nhưng kiểu mảng một
chiều với phần tử thuộc kiểu char khác với kiểu xâu (khai báo bằng từ khóa
string).
* Điểm giống và khác nhau cơ bản giữa mảng 1 chiều và xâu:
- Giống nhau: Cùng là kiểu dữ liệu có cấu trúc, có thể truy cập vào từng phần tử
riêng biệt.
- Khác nhau:
+ Xâu vừa là kiểu dữ liệu có cấu trúc vừa là kiểu dữ liệu vô hướng, vì vậy có thể
truy cập vào toàn bộ xâu như một dữ liệu đơn;
+ Các phần tử của xâu chỉ có thể là kí tự;
+ Ở một số ngôn ngữ lập trình, xâu có độ dài hạn chế;
+ Mảng có thể có kích thước rất lớn;

+ Phần tử của mảng có thể có kiểu bất kì.
2.3.1.3. Hàm chuẩn trên kiểu xâu cho kết quả là một giá trị, tùy theo hàm cụ
thể mà giá trị đó có thể là số, kí tự hay xâu.
Ví dụ: - Length(s), pos(s1,s2) cho kết quả là số nguyên không âm.
- Copy (s,vt,n) cho kết quả là một xâu.
5


- Upcase(c) cho kết quả là một kí tự, chú ý c phải là một phần tử của xâu
hay một kí tự.
* Một số thủ tục và hàm chuẩn dùng để xử lí xâu

Ngoài các hàm và thủ tục chuẩn đã được trình bày trong sách giáo khoa, tôi
cung cấp thêm cho học sinh một số hàm và tục nữa để học sinh có thể áp dụng
giải các bài toán kiểu xâu tốt hơn. Nhất là các đối tượng ôn luyện học sinh
giỏi.
- Thủ tục STR(N,st): Thủ tục này thực hiện việc chuyển đổi giá trị số N thành
kiểu xâu và đưa kết quả vào biến st.
Ví dụ:
Giá trị N
Biểu thức
Kết quả
1500
Str(N,st)
‘1500’
- Thủ tục VAL(st,N,code): chuyển đổi giá trị st thành đại lượng kiểu nguyên
hay thực và ghi kết quả vào biến N. Biến code là biến kiểu integer. Nếu việc
chuyển đổi không có lỗi thì code sẽ có giá trị 0, ngược lại code chứa số chỉ vị
trí kí tự đầu tiên phát sinh lỗi và khi đó giá trị của N là không xác định.
Ví dụ:

Giá trị st
Biểu thức
Kết quả
‘1500’
val(st,N,code) Code=0, N=1500
’14.2A+02’
val(st,N,code) Code=5
- Hàm CONCAT(s1,s2,…,sn): trả về xâu thu được từ việc ghép các xâu s1,s2,
…,sn.
Ví dụ:
Biểu thức
Kết quả
concat(‘Toi’, ‘hoc’, ‘bai’)
‘Toi hoc bai’
- Hàm CHR(X): Cho kí tự có mã X trong bảng mã ASCII.
Ví dụ: chr(65)= ‘A’; chr(97)= ‘a’
- Hàm ORD(ch): cho mã của kí tự ch trong bảng mã ASCII.
Ví dụ: ord(‘A’) = 65; ord(‘a’) = 97
2.3.1.4. Xâu được tạo thành bởi các kí tự, trong đó có thể có dấu cách. Dấu
cách thể hiện trong các văn bản là phần trống ngăn cách giữa hai từ viết liên
tiếp;
2.3.1.5. Khi sử dụng lệnh gán, ta có thể gán trị là một xâu kí tự cho một biến
xâu kí tự nhưng việc gán trị là một xâu kí tự cho một biến kiểu kí tự là không
hợp lệ dù xâu đó có độ dài bằng 1;
2.3.1.6. Tham số của các hàm và thủ tục chuẩn phải hợp lí,.

Chẳng hạn không thể dùng insert(s1,s2,10) khi length(s2)<10.[1].
6



2.3.2. Khắc phục sai lầm của học sinh trong lập trình kiểu xâu
Xét bài toán: Nhập vào từ bàn phím một xâu. Thay thế tất cả các cụm kí tự
‘anh’ bằng cụm kí tự ‘em’. (Bài 3.sách giáo khoa trang 73 Tin học 11).[2].
Tôi thấy rằng một số học sinh đã có tư duy như sau:
Duyệt các kí tự của xâu, cho đến khi gặp kí tự ‘anh’ thì thay thế bằng kí tự ’em’.
Dẫn đến chương trình được viết là:
Var s: string;
i: byte;
begin
write('Nhap vao xau: ');
readln(s);
for i:=1 to length(s) do
if (s[i]='a') and (s[i+1]='n')and(s[i+2]='h') then
begin
s[i]:='e';
s[i+1]:='m';
end;
write('Xau tiep theo la',s);
readln;
end.
Như vậy, cách tư duy này không đúng vì kí tự ‘h’ đã không bị loại bỏ, mặc dù
từ ‘anh’ đã được thay thế thành từ ‘em’ nhưng chữ h đã không bị xóa đi trong xâu.
Mà theo yêu cầu của đề bài là phải xóa cả chữ ‘anh’ đi. Tuy nhiên đây là tư duy của
học sinh khi mới học về xâu, đó là tư duy hết sức bình thường. Nhưng chúng ta
cũng cần định hướng đúng đắn để học sinh không tư duy lệch lạc.
*Tôi đã chỉ ra lỗi sai đồng thời khắc phục lỗi đó như sau:
Trước hết tìm vị trí xâu con ‘anh’ trong xâu s đã cho, xóa xâu con này đi rồi
chèn xâu ‘em’ vào vị trí đó. Lặp đi lặp lại điều này cho đến khi không tìm thấy xâu
‘anh’ cần thay thế trong xâu s nữa.
Tôi đã gợi mở cho học sinh bằng cách đặt câu hỏi: Với các hàm và thủ tục

chuẩn đã biết khi học về kiểu xâu, liệu có tìm được vị trí xuất hiện một xâu con,
thực hiện xóa một xâu con, chèn một xâu con hay không? Câu hỏi này sẽ gợi cho
học sinh nhớ lại và vận dụng hàm pos, các thủ tục chuẩn delete, insert.
Tôi đã xây dựng một dàn ý chương trình như sau:
{Phần khai báo};
Begin
{Nhập vào xâu s};
{Chừng nào còn tìm thấy xâu con ‘anh’ trong xâu s còn làm ba việc sau:
7


- Tìm vị trí bắt đầu của xâu ‘anh’;
- Xóa xâu ‘anh’ vừa tìm thấy;
- Chèn xâu ‘em’ vào xâu s tại vị trí trước đây xuất hiện xâu ‘anh’};
- {in kết quả xâu s};
End.
Tôi yêu cầu học sinh chi tiết hóa bằng các câu lệnh để có một chương trình hoàn
chỉnh. Học sinh đã làm rất tốt.
program bai3;
uses crt;
var s: string;
i,vt: byte;
begin
write('Nhap vao xau: ');
readln(s);
while pos('anh',s <>0 do
begin
vt:=pos(‘anh’,s);
delete(s,vt,3);
insert('em',s,vt);

end;
write('Xau da thay the la',s);
readln;
end.

2.3.3. Rèn luyện kỹ năng cho học sinh qua một số bài tập đặc trưng
2.3.3.1. Bài toán kiểm tra tính đối xứng của một xâu
Bài 1. Nhập vào từ bàn phím một xâu. Kiểm tra xâu đó có phải là xâu đối
xứng hay không. Xâu đối xứng có tính chất: đọc nó từ phải sang trái cũng thu được
kết quả giống như đọc từ trái sang phải(còn được gọi là xâu palindrome). (Bài 1
sách giáo khoa Tin học 11 trang 73).[2].
Với bài toán này, trước tiên tôi giới thiệu một vài xâu đối xứng và xâu không
đối xứng cho học sinh. Xâu đối xứng: 12321; RADAR. Xâu không đối xứng:
12345; TOMATO…
Khi làm việc với chương trình có sẵn trong sách giáo khoa, học sinh dễ dàng
tiếp cận hơn. Hơn nữa các em cũng đã được làm quen với cách tạo xâu mới từ một
xâu ban đầu trong hai ví dụ đã được trình bày trong tiết lý thuyết về kiểu xâu.
Chương trình này linh hoạt duyệt xâu ban đầu theo thứ tự ngược lại (từ cuối xâu
quay ngược về đầu xâu) nên tạo được xâu đảo ngược của xâu ban đầu và giải quyết
được bài toán đặt ra (kiểm tra xâu có đối xứng hay không).
Với yêu cầu viết lại chương trình không dùng biến xâu p, tôi đã gợi ý cho học
sinh khai thác khả năng tham chiếu đến từng kí tự trong xâu thông qua vị trí của kí
tự này. Sau đó chỉ cần so sánh các cặp kí tự ở vị trí đối xứng nhau để kết luận xâu
8


đó có là palindrome hay không. Chỉ cần phát hiện được một cặp kí tự ở vị trí đối
xứng nhau nhưng khác nhau là đủ kết luận xâu đó không là palindrome. Có hai cách
để học sinh có thể tư duy:
- Cách thứ nhất là dựa trên tư duy phản chứng:

Giả sử như lúc đầu xâu đó là xâu đối xứng, nếu có một tính chất nào đó khiến xâu
đó không là xâu đối xứng, thì giả sử sẽ sai và ta kết thúc việc kiểm tra. Còn không
thì xâu đó vẫn là xâu đối xứng. Tôi đã xây dựng dàn ý như sau:
{Phần khai báo};
Begin
{Nhập vào xâu s};
{Xác định độ dài của xâu};
{Khởi tạo kt, tạm coi xâu s vừa nhập là palindrome};
{So sánh cặp kí tự đối xứng:
Nếu s[i] <>s[length(s)-i+1] thì xâu không phải là palindrome};
{in kết quả};
End.
Tôi yêu cầu học sinh chi tiết hóa bằng các câu lệnh để có một chương trình hoàn
chỉnh. Học sinh đã làm rất tốt.
program xaudoixung;
uses crt;
var s:string;
kt:boolean;
i:byte;
begin
write('Nhap vao xau s=');
readln(s);
kt:=true;
for i:=1 to length(s) div 2 do
if s[i]<>s[(length(s) - i) +1] then
kt:=false;
if kt then write('Xau doi xung')
else write('xau khong doi xung');
readln;
end.

- Cách thứ hai dựa trên việc phát triển thuật toán đếm số lượng các phần tử trong
một mảng hoặc một xâu, dựa vào tính chất của xâu đối xứng. Nếu xâu đó là xâu đối
xứng thì với i từ 1 tới length(s) div 2, ta luôn có tính chất s[i]=s[(length(s)-i+1]. Vậy
ta tìm cách đếm xem từ 1 tới length(s) div 2 có bao nhiêu lần tính chất
s[i]=s[(length(s)-i+1] này đúng. Nếu có length(s) div 2 lần tính chất này đúng thì
xâu đó là xâu đối xứng, còn nếu có 9


không đối xứng. Cách này không dùng vòng lặp for-do mà dùng while-do và không
cần dùng biến logic.
Sau đây là chương trình:
program xaudoixung;
uses crt;
var s:string;
i,m:byte;
begin
clrscr;
write('Nhap vao xau s=');
readln(s);
x:=length(s);
i:=1;
while (i<=x div 2) and(s[i]=s[x-i+1]) do
i:=i+1;
if i >(x div 2) then write('Xau doi xung')
else write('xau khong doi xung');
readln;
end.
Bài 2. Một số nguyên gọi là palindrome nếu nó đọc từ trái sang cũng bằng đọc từ
phải sang. Ví dụ 121 là một số palindrome. Nhập một dãy n phần tử nguyên dương

từ bàn phím, 5<= n<=20 và các phần tử có 2 đến 4 chữ số. In ra các số là
palindrome trong dãy.
* Ý tưởng:
Một số là palindrome thì xâu tương ứng của nó là xâu đối xứng. Ta sẽ xây
dựng một hàm kiểm tra một số có phải là palindrome không bằng cách chuyển số
đó thành xâu và kiểm tra xâu đó có đối xứng không?
Chương trình gợi ý để học sinh tham khảo
uses crt;
var n : integer;
a : array[1..20] of integer;
{Thủ tục nhập dữ liệu}
procedure nhap;
var i : integer;
begin
clrscr;
repeat
write('n= '); readln(n);
if (n<=20) and (n>=5) then break; {nếu đã thoả mãn thì thoát khỏi vòng lặp}
10


writeln('Yeu cau 5<=n<=20. Nhap lai!');
until false;
for i := 1 to n do
repeat
write('A[',i,']='); readln(a[i]);
if (a[i]<=9999) and (a[i]>=10) then break; {a[i] có 2 đến 4 chữ số}
writeln('Yeu cau cac phan tu co 2 den 4 chu so. Nhap lai!');
until false;
end;

{Hàm kiểm tra bằng các kiểm tra xâu đối xứng}
function palindrome(k : integer): boolean;
var x,y : string;
i : integer;
begin
str(k,x); {chuyển k thành xâu x}
y := '';
for i := length(x) downto 1 do y := y + x[i];
{nếu x là đối xứng thì k là palindrom}
if x=y then palindrome := true else palindrome := false;
end;
{In kết quả:}
procedure palin;
var i : integer;
begin
writeln('Cac so la palindrome trong day:');
for i := 1 to n do
if palindrome(a[i]) then writeln(a[i]);
readln;
end;
(* Chương trình chính *)
BEGIN
nhap;
palin;
END. [4].
2.3.3.2. Bài toán đếm số lần xuất hiện các kí tự trong một xâu
Xét bài toán: Viết chương trình nhập từ bàn phím một xâu kí tự S và thông
báo ra màn hình số lần xuất hiện của mỗi chữ cái tiếng Anh trong S (không phân
biệt chữ hoa hay chữ thường).( Bài 2 Trang 73 sách giáo khoa Tin học 11). [2].
*Để giải bài toán này, tôi đã gợi ý và dẫn dắt cho học như sau:

Có thể dùng mảng một chiều với các phần tử được đánh chỉ số từ 1 đến 26
(Có tất cả 26 chữ cái từ ‘A’… ‘Z’), dùng để ghi nhận số lần xuất hiện trong xâu S
của các kí tự (tương ứng) từ ‘A’ đến ‘Z’.Ta dùng hàm ord(ch) cho giá trị là mã
ASCII thập phân của kí tự là giá trị của ch.
11


Ord(‘A’)-ord(‘A’)+1=1
Ord(‘B’)-ord(‘A’)+1=2
Ord(‘C’)-ord(‘A’)+1=3

Ord(‘Z’)-ord(‘A’)+1=26
Tổng quát: Ord(ch)= i+ord(‘A’)-1
Ngược lại, từ chỉ số i của mảng có thể biết phần tử thứ i ghi nhận số lần xuất
hiện của kí tự nào, bằng cách dùng hàm chr(X). Như vậy, chr(i+ord(‘A’)-1) là kí tự
được đếm bằng phần tử thứ i của mảng dem.
Do một kí tự xuất hiện trong xâu S có thể không phải là một chữ cái nên khi
duyệt lần lượt từng kí tự trong xâu S, cần kiểm tra xem kí tự đó có phải là chữ cái
hay không để ghi nhận số lần xuất hiện của nó, từ đó có thể viết được đoạn chương
trình thực hiện việc duyệt từng phần tử của xâu và đếm. Khi duyệt đến kí tự thứ i
trong xâu S, nếu S[i] là chữ cái thì đếm tăng cho S[i], nghĩa là tăng 1 cho
dem[ord(s[i])- ord(‘A’)+1].
Dàn ý của chương trình:
{Phần khai báo}
Begin
{Nhập xâu S}
n:=length(S);
{Khởi trị cho mảng dem}
For i:=1 to n do
{Nếu S[i] là chữ cái thì dem tăng cho S[i]}

For i:=1 to 26 do
{Thông báo số lần xuất hiện của chr(i+ord(‘A’)-1)}
End.
Với dàn ý này học sinh dễ dàng hoàn thiện chương trình.
* Đối với học sinh khá, giỏi tôi hướng dẫn dùng một mảng với chỉ số là kí tự từ ‘A’
đến ‘Z’ để ghi nhận số lần xuất hiện của các kí tự trong xâu S. Tôi xây dựng dàn ý
chương trình như sau:
{Phần khai báo}
Begin
{Nhập xâu S}
n:=length(S);
{Khởi trị cho mảng dem}
For i:=1 to n do
{Nếu S[i] là chữ cái thì dem tăng cho S[i]}
For ch:= ‘A’ to ‘Z’ do
{Thông báo số lần xuất hiện của ch}
End.
12


*Tôi yêu cầu học sinh chi tiết hóa bằng các câu lệnh để có một chương trình
hoàn chỉnh. Học sinh đã làm rất tốt.
Program bai2;
Uses crt;
Var S:string[30];
ch,x: char;
i: byte;
dem:array['A'..'Z'] of byte;
Begin
clrscr;

write('Nhap vao xau s=');
readln(s);
for ch:='A' to 'Z' do dem[ch]:=0;
for i:=1 to n do
begin
x:=upcase(s[i]);
if (x>='A') and (x<='Z')
then
dem[x]:=dem[x]+1;
end;
for ch:='A' to 'Z' do
if dem[ch]<>0 then
writeln('So luong ki tu',ch,'la',dem[ch]);
readln;
End.
2.3.3.3. Bài toán chuẩn hóa xâu
Bài 1. Hãy lập trình:
- 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.
(Bài 4.40 sách bài tập Tin học 11 trang 45).[3].
* Trước hết, tôi cho ví dụ về xâu chưa được chuẩn hóa (là xâu còn chứa ký tự
trắng dư thừa hay còn gọi là dấu cách, kí tự trống) và xâu đã chuẩn hóa.
Chẳng hạn - là dấu cách
Xâu chưa chuẩn hóa: ‘--Tin---học--’
Xâu đã được chuẩn hóa: ‘Tin-học’
Tôi định hướng và diễn giải cho học sinh như sau:

- Kiểm tra phần tử trong xâu có phải là dấu cách (kí tự trống) hay không? Nếu đúng
thì xóa kí tự trống đó cho đến khi không còn kí tự trống ở đầu xâu.
13


- Kiểm tra từ đầu đến cuối xâu, nếu có hai kí tự trống liên tiếp thì xóa đi một kí tự
trống, thực hiện công việc xóa cho đến khi giữa các từ trong xâu chỉ cách nhau một
kí tự trống.
- Sau khi xử lí các kí tự trống dư thừa ở đầu xâu, giữa xâu. Ta xử lý tiếp kí tự trống
dư thừa ở cuối xâu bằng cách kiểm tra kí tự cuối cùng có phải là kí tự trống hay
không. Nếu đúng thì xóa cho đến khi kí tự cuối cùng của xâu không phải là kí tự
trống.
Tôi lập dàn ý của chương trình như sau:
{Phần khai báo}
Begin
{Nhập xâu st}
{Xóa kí tự trống dư thừa xuất hiện ở đầu tiên của xâu(nếu có)}
{Chừng nào kí tự đầu tiên trong xâu s là kí tự trống thì xóa kí tự trống đó cho đến
khi đầu xâu không phải là kí tự trống}
{Xóa kí tự trống dư thừa giữa các từ (nếu có)}
{Chừng nào trong xâu st xuất hiện hai kí tự trống liên tiếp trong xâu thì xóa đi một
kí tự trống dư thừa}
{Xóa kí tự trống dư thừa cuối cùng của xâu(nếu có)}
{Chừng nào kí tự cuối cùng là kí tự trống thì xóa kí tự trống đó}
{in kết quả xâu st};
End.
*Tôi yêu cầu học sinh chi tiết hóa bằng các câu lệnh để có một chương trình
hoàn chỉnh. Học sinh đã làm rất tốt.
program chuanhoaxau;
var st:string;

i,x,vt:byte;
begin
write('Nhap xau: ');
readln(st);
{xoa ky tu trong du thua xuat hien dau xau}
while st[1]=' ' do
delete(st,1,1);
{xoa ki trong du thua giua cac tu}
vt:=pos(' ',st);
while vt<>0 do
begin
delete(st,vt,1);
vt:=pos(' ',st);
end;
{xoa ki tu trong du thua xuat hien cuoi xau}
x:=length(st);
while st[x]=' ' do
begin
14


delete(st,x,1);
x:=length(st);
end;
write('Xau da chuan hoa: ',st);
readln;
end.
Bài 2. Nhập vào một xâu s khác rỗng và thực hiện chuẩn hoá xâu, tức là:
- Xoá các dấu cách thừa;
- Chuyển những kí tự đầu từ thành chữ hoa, những kí tự khác thành chữ thường.

Chương trình gợi ý để học sinh tham khảo
var s : string;
procedure chuanhoa(var s : string); {s là tham biến để có thể thay đổi trong chương
trình con}
var i : integer;
begin
while s[1]=' ' do delete(s,1,1); {xoá các kí tự cách thừa ở đầu xâu}
while s[length(s)]=' ' do delete(s,length(s),1); {xoá các kí tự cách thừa ở cuối xâu}
{xoá các kí tự cách thừa ở giữa các từ: nếu s[i-1] là cách thì s[i] là dấu cách là thừa.
Phải dùng vòng lặp for downto vì nếu trong quá trình xoá ta làm giảm chiều dài của
xâu, nếu for to sẽ không dừng được.}
for i := length(s) downto 2 do
if (s[i]=' ') and (s[i-1]=' ') then delete(s,i,1);
{Chuyển kí tự đầu xâu thành chữ hoa}
s[1] := Upcase(s[1]);
for i := 2 to length(s) do
if s[i-1]=' ' then s[i] := Upcase(s[i]) {Chuyển s[i] là kí tự đầu từ thành chữ
hoa.}
else if s[i] in ['A'..'Z'] then {s[i] là kí tự chữ hoa không ở đầu một từ}
s[i] := chr(ord(s[i]) + 32); {thì phải chuyển thành chữ thường}
end;
BEGIN
write('Nhap vao 1 xau s:');
readln(s);
chuanhoa(s);
writeln('Xau s sau khi chuan hoa:',s);
readln;
END.[4].

15



2.3.3.4. Bài toán mã hóa và giải mã một xâu
Xét bài toán:Viết chương trình để mã hóa và giải mã một xâu kí tự bằng cách
đảo ngược các bit của từng kí tự trong xâu.

Sau đây là chương trình gợi ý để học sinh tham khảo và tự hoàn thiện
chương trình.
Uses crt;
Var st:string;
{Hàm đảo bit ký tự c}
Function DaoBit(c:char):char;
Var n,i,s,bitcuoi,Mask:byte;
Begin
{Đổi ký tự sang số}
n:=ORD(c);
{s: kết quả đảo bit, Mask: mặt nạ dùng để bật bit thứ i}
s:=0;
Mask:=128;
For i:=1 To 8 Do {duyệt qua 8 bit của n}
Begin
{Lấy bit cuối cùng của n: bit cực phải}
bitcuoi:=n AND 1;
n:=n shr 1; {loại bỏ bit cuối cùng: n:=n DIV 2}
{Bật bit thứ i lên: từ trái sang phải}
if bitcuoi=1 then s:=s OR Mask;
Mask:=Mask shr 1; { Mask:= Mask DIV 2}
End;
DaoBit:=CHR(s);
End;

Function MaHoa(st:string):string;
Var i:Byte;
Begin
{Đảo bit từng ký tự trong xâu st}
For i:=1 To Length(st) Do st[i]:=DaoBit(st[i]);
Mahoa:=st;
End;
Begin
Write('Nhap xau: '); Readln(st);
st:=MaHoa(st);
Writeln('Xau sau khi ma hoa: ',st);
Readln;
st:=MaHoa(st);
Writeln('Xau sau khi giai ma: ',st);
Readln;
16


End. [4].
2.3.3.5. Bài toán nén và giải nén một xâu
Xét bài toán: Một xâu kí tự có thể được nén theo cách sau: Một xâu con gồm
n (n>1) kí tự giống nhau, chẳng hạn: gồm n kí tự ‘a’ sẽ được ghi thành na. Ví dụ xâu
‘aaaabbcd’ sẽ được nén thành 4a2bcd. Hãy viết chương trình nén và giải nén một
xâu kí tự nhập vào từ bàn phím. (Chú ý trong xâu được nén phải không có chữ số).
[4]
* Tôi đã hướng dẫn học sinh như sau:
Với việc nén xâu, ta lần lượt đếm các kí tự giống nhau liên tiếp trong xâu và
sử dụng một xâu kq để lưu kết quả tìm được cho đến khi xét hết xâu.
Việc giải nén được thực hiện ngược lại.
Chương trình gợi ý để học sinh tham khảo và tự hoàn chỉnh chương trình.

var s1,s2:string;
procedure doc;
begin
Write(‘Nhap xau s1:’);
readln(s1);
Write(‘Nhap xau s2:’);
readln(s2);
procedure nen;
var s,kq:string;
i,d:integer;
ch:char;
begin
d:=1; s1:=s1+#32;ch:=s1[1]; kq:='';
for i:=2 to length(s1) do
if s1[i]=s1[i-1] then inc(d)
else
begin
str(d,s);
if d<>1 then kq:=kq+s+ch else kq:=kq+ch;
d:=1;
ch:=s1[i];
end;
writeln(kq);
end;
procedure giainen;
var s,kq,so:string;
i, j,code,n:integer;
ch:char;
17



begin
i:=1; kq:='';
repeat
so:='0';
while s2[i] in ['1'..'9'] do begin so:=so+s2[i];inc(i); end;
val(so,n,code);
if n>1 then
for j:=1 to n do kq:=kq+s2[i]
else kq:=kq+s2[i];
inc(i);
until i> length(s2);
writeln(kq);
end;
begin
doc;
nen;
giainen;
end.
Tôi đã củng cố lại một số kiến thức cần thiết và bổ sung thêm một số hàm và
thủ tục xử lí xâu. Chỉ ra một số lỗi sai và cách khắc phục các lỗi đó. Sau đó tôi tập
trung trình bày thật cặn kẽ, kỹ lưỡng một số bài toán áp dụng cơ bản để học sinh dễ
dàng lĩnh hội kiến thức, tiếp cận bài toán tốt hơn, hình thành khả năng tư duy cho
các em. Trên cơ sở đó học sinh có cái nhìn đúng đắn hơn, cách tư duy linh hoạt hơn
với các bài toán khác nhau.
Sau khi đưa ra và giải quyết các ví dụ ứng với những giải pháp nêu trên, tôi đã
yêu cầu học sinh sử dụng kiến thức đã học về kiểu xâu để giải quyết các bài toán
với nhiều dạng khác nhau. Học sinh đã biết vận dụng linh hoạt và sáng tạo cho từng
bài toán cụ thể. Các em đã chủ động xác định được ý tưởng của thuật toán cho công
việc lập trình của mình.


2.4. HIỆU QUẢ CỦA SÁNG KIẾN KINH NGHIỆM
Sau khi áp dụng các giải pháp trên để giảng dạy cho học sinh, chất lượng học tập
của học sinh tăng lên rõ rệt. Học sinh đã biết vận dụng rất linh hoạt các kiến thức cơ
bản về kiểu xâu để giải quyết từng bài toán cụ thể và có thể chủ động đưa ra ý
tưởng cho các bài toán đó một cách sáng tạo. Cách tư duy cũng sáng sủa hơn.Từ bài
này có thể suy diễn sang bài khác một cách logic và hiệu quả.
Chất lượng giảng dạy ở các lớp năm học 2015-2016 khi chưa áp dụng các giải
pháp nêu trên. Kết quả khảo sát như sau:
LỚP

SĨ SỐ

GIỎI
SL %

KHÁ
SL
%

TB
SL

%

YẾU
SL
%

KÉM

SL
%

18


11A
11B

50
55

2
3

4%
5%

10 20% 20 40% 13 26%
15 27% 25 46% 10 18%

5
2

10%
4%

Chất lượng giảng dạy ở các lớp năm học 2016-2017 khi áp dụng các giải pháp
nêu trên. Kết quả khảo sát như sau:
LỚP


SĨ SỐ

11C
11D

55
50

GIỎI
SL
%

KHÁ
SL
%

TB
SL

YẾU
SL %

%

10 18% 30 55% 15 27%
8 16% 25 50% 15 30%

0
2


0%
4%

KÉM
SL %

0
0

0%
0%

Như vậy, có thể thấy sử dụng các giải pháp trong SKKN của tôi thực sự có hiệu
quả.

3. KẾT LUẬN VÀ KIẾN NGHỊ
Để đổi mới phương pháp dạy học theo hướng tích cực, nhằm nâng cao chất
lượng giáo dục. Bằng những kinh nghiệm đã tích lũy được trong quá trình giảng
dạy, tôi đã chọn đề tài: “Một số phương pháp rèn luyện tư duy lập trình Pascal
cho học sinh qua các dạng bài tập kiểu xâu” để thực hiện. Mặc dù với những giải
pháp mà tôi đưa ra để thực hiện đã đem lại hiệu quả cao cũng như chất lượng dạy
học của mình. Song không tránh khỏi những thiếu sót. Vậy tôi rất mong sự đóng
góp ý kiến của các bạn đồng nghiệp để SKKN của tôi được hoàn thiện hơn.
Tôi xin chân thành cảm ơn!
XÁC NHẬN CỦA THỦ TRƯỞNG ĐƠN VỊ

Thanh Hóa, ngày 20 tháng 5 năm 2017
CAM KẾT KHÔNG COPY


Tôi xin cam đoan đây là SKKN của bản
thân, không sao chép nội dung của
người khác.

Phạm Thị Nhung

TÀI LIỆU THAM KHẢO
1. Sách giáo viên Tin học 11 - Hồ Sĩ Đàm chủ biên
2. Sách giáo khoa Tin học 11- Hồ Sĩ Đàm chủ biên
19


3. Sách bài tập Tin học 11

- Hồ Sĩ Đàm chủ biên

4. Một số bài tập tham khảo trên Internet.

DANH MỤC ĐỀ TÀI SKKN
STT
1
2

3

Tên đề tài SKKN
Sử dụng Microsoft Access trong quản
lý trường học
Phát huy tính chủ động sáng tạo của
học sinh thông qua một số ví dụ cụ thể

về chương trình con để giải quyết các
bài toán lập trình
Hướng dẫn học sinh xây dựng thuật
toán hình thành kỹ năng viết chương
trình

Cấp đánh
giá xếp
loại

Kết quả
đánh giá
xếp loại

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

Cấp Tỉnh

C

2009

Cấp Tỉnh

C

2011


Cấp Tỉnh

B

2015

20



×