SÁNG KIẾN KINH NGHIỆMMỘT SỐ KIẾN THỨC CƠ BẢN VỀ CHUỖI STRING TRONG C/C++ NHẰM GIÚP HỌC SINH TIẾP CẬN VỚI NGÔN NGỮ LẬP TRÌNH C/C++ KHI ÔN LUYỆN VÀ THI HỌC SINH GIỎI.. Trong chương trình
Trang 1SÁNG KIẾN KINH NGHIỆM
MỘT SỐ KIẾN THỨC CƠ BẢN VỀ CHUỖI (STRING) TRONG C/C++ NHẰM GIÚP HỌC SINH TIẾP CẬN VỚI
NGÔN NGỮ LẬP TRÌNH C/C++
KHI ÔN LUYỆN VÀ THI HỌC SINH GIỎI.
Người thực hiện: Trương Văn Phát Chức vụ: Giáo viên
SKKN thuộc lĩnh vực (môn): Tin học
THANH HOÁ, NĂM 2021
Trang 21 GD ĐT Giáo dục Đào tạo
4 CNTT & TT Công nghệ thông tin và truyền thông
Trang 31.1 Lý do chọn đề tài 1
1.2 Phạm vi và đối tượng đề tài 1
1.3 Mục đích đề tài 1
1.4 Điểm mới của sáng kiến 1
1.5 Phương pháp nghiên cứu 1
1.5.1 Phương pháp nghiên cứu lý thuyết 1
1.5.2 Phương pháp tham vấn chuyên gia 2
2 Nội dung sáng kiến kinh nghiệm 2
2.1 Cơ sở lý luận của sáng kiến kinh nghiệm 2
2.2 Thực trạng chất lượng giảng dạy môn tin học tại trường THPT Dân tộc nội trú tỉnh Thanh Hoá (cơ sở thực nghiệm) 2
2.2.1 Đặc điểm tình hình 2
2.2.2 Thực trạng của vấn đề 2
3 Một số kiến thức cơ bản về chuỗi (String) trong ngôn ngữ lập trình C/C++ 3
3.1 Tổng quan về chuỗi (String) trong C/C++ 3
3.2 Chuỗi Ký Tự C-Style 3
3.3 Kiểu chuỗi (String) trong thư viện STL của C++ 3
3.3.1 Các phương thức, phép toán tiện ích của kiểu chuỗi (String) trong C/C++ 3
3.3.2 Các phương thức chèn, xóa, lấy chuỗi con: 5
3.3.3 Phương thức so sánh 7
3.3.4 Các phương thức tìm kiếm và thay thế 7
5 Hiệu quả của sáng kiến 13
6 Kết luận, kiến nghị 13
6.1 Kết luận 13
6.2 Kiến nghị, đề xuất 13
TÀI LIỆU THAM KHẢO 14
Trang 41 Mở đầu
1.1 Lý do chọn đề tài
Tại các kỳ thi học sinh giỏi các cấp đòi hỏi học sinh cần phải có tư duy thuật toán và lập trình tốt Trong chương trình hiện hành, nội dung lập trình nói riêng
và thuật toán nói chung chủ yếu được dạy tập trung ở lớp 8 và lớp 11 theo cách tiếp cận hàn lâm, nặng về học ngôn ngữ lập trình (Pascal), làm cho HS khó tiếp thu và không hiệu quả
Hầu hết chúng ta đều biết và sử dụng ngôn ngữ lập trình Pascal Đó là ngôn ngữ được sử dụng nhiều nhất trong các kì thi tin học ở nước ta hiện nay Tuy nhiên, C/C++ cũng là một ngôn ngữ được sử dụng rộng rãi để giải các bài toán tin học; đôi khi nó cung cấp một số thuận lợi nhất định so với Pascal
Với định hướng mới của chương trình giáo dục bộ môn tin học thì ngôn ngữ lập trình Pascal sẽ được thay thế bằng một ngôn ngữ khác có thể là Python… Tuy nhiên, ngôn ngữ C/C++ lại được quy định trong các kỳ thi chọn học sinh giỏi các cấp từ rất nhiều năm nay Trong khi đó các ngôn ngữ khác như Python … lại chưa được đề cập tới trước đó Và sự thật là hiện nay có rất nhiểu trường đã và đang sử dụng ngôn ngữ lập trình C/C++ như là công cụ để giảng dạy cho học sinh, đặc biệt là học sinh đội tuyển dự thi học sinh giỏi cấp trường, cấp tỉnh và cấp quốc gia môn tin học
C/C++ là ngôn ngữ lập trình khá phổ biến, có kiểu dữ liệu tĩnh và hỗ trợ hầu
hết các phương pháp lập trình Chuỗi (String) trong C/C++ phức tạp hơn khá nhiều so với chuỗi trong Pascal
Xuất phát từ những lý do trên và qua nhiều năm giảng dạy, bồi dưỡng học
sinh giỏi Tôi xin đề cập tới đề tài: “Một số kiến thức cơ bản về chuổi (String)
trong C/C++ nhằm giúp học sinh tiếp cận với ngôn ngữ lập trình C/C++ khi
ôn luyện và thi học sinh giỏi ”.
1.2 Phạm vi và đối tượng đề tài
- Phạm vi: Nghiên cứu thực tế học sinh trường THPT Dân tộc nội trú tỉnh Thanh Hóa
- Đối tượng: Nghiên cứu giải pháp nhằm nâng cao chất lượng dạy ôn luyện và thi học sinh giỏi môn tin học ở trường THPT
1.3 Mục đích đề tài
Tìm hiểu và nêu các kiến thức cơ bản về chuổi (String) trong C/C++ nhằm
giúp học sinh tiếp cận với ngôn ngữ lập trình C/C++ khi ôn luyện và thi học sinh giỏi.
1.4 Điểm mới của sáng kiến
Đề xuất các kiến thức cơ bản về Chuỗi (String) trong ngôn ngữ C/C++
1.5 Phương pháp nghiên cứu
1.5.1 Phương pháp nghiên cứu lý thuyết.
Nghiên cứu tài liệu và các công trình khoa học liên quan đến kiến thức lập trình trong C/C++
Nghiên cứu cấu trúc, nội dung sách giáo khoa tin học THPT
Trang 5 Nghiên cứu các kiến thức liên quan với các loại ngôn ngữ lập trình khác nhau nhằm tìm ra tính tối ưu trong ngôn ngữ lập trình C/C++
1.5.2 Phương pháp tham vấn chuyên gia.
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
* Giới thiệu về ngôn ngữ lập trình C++
a Ngôn ngữ:
C++ là một ngôn ngữ lập trình rất mạnh C++ hỗ trợ cả lập trình cấu trúc (structural, như Pascal) và lập trình hướng đối tượng (như Java, C#)
Nhược điểm thường gặp khi dùng C++ để giải bài tập đó là chương trình C++ khó gỡ rối, vì chưa có một phần mềm hỗ trợ gỡ rối nào đủ mạnh GNU C++ cũng biên dịch chậm hơn so với C#
b Trình biên dịch:
Trình biên dịch dùng trong các kỳ thi và Online Judge đó là G++, một trình biên dịch mã nguồn mở cho ngôn ngữ C++
Để tận dùng công cụ gỡ rối, đôi khi các bạn cần dùng trình biên dịch Visual C/C++ (msvc) của Microsoft Trình biên dịch này so với G++ có một vài điểm khác biệt cần lưu ý khi giải bài tập Nhưng nhìn chung, có thể dùng chương trình viết cho VC++ để nộp bài mà không gây ra lỗi biên dịch nào đáng kể
2.1.1.3 Ưu điểm của C/C++:
Sức mạnh của C/C++ đến từ STL, viết tắt của Standard Template Libary, một thư viện lớn các class và thủ tục chuẩn cho C/C++ Các trình biên dịch mới như G++ và VS đều hỗ trợ tốt STL
2.2 Thực trạng chất lượng giảng dạy môn tin học tại trường THPT Dân tộc nội trú tỉnh Thanh Hoá (cơ sở thực nghiệm).
2.2.1 Đặc điểm tình hình
Trường THPT Dân tộc nội trú tỉnh Thanh Hóa là một trường chuyên biệt, 100% học sinh là người dân tộc thiểu số, sinh sống tại 11 Huyện miền núi của Tỉnh Thanh Hóa được hưởng chế độ chính sách của nhà nước và của Tỉnh
Cơ bản cơ sở vật chất nhà trường đã được cấp, cơ quan quản lý trang bị đầy đủ,
đã được trang bị máy chiếu, máy tính, phòng tin học phục vụ cho công tác dạy và học của nhà trường, nhưng trường được xây dựng từ những năm 1992, nên không gian phòng học nhỏ, có nhiều hạn chế trong triển khai giờ dạy
Đội ngũ giáo viên trẻ, năng động, nhiệt tình trong công tác cùng với 540 học sinh toàn trường được chia làm 18 lớp:
Khối 10: 06 lớp với 180 học sinh
Khối 11: 06 lớp với 180 học sinh
Khối 12: 06 lớp với 180 học sinh
2.2.2 Thực trạng của vấn đề
a Thuận lợi:
Được sự quan tâm của Sở Giáo dục & Đào tạo, nhà trường được trang bị 02 phòng máy tính, ngoài ra cũng có một số phòng học được trang bị máy chiếu, máy tính phục vụ cho nhu cầu công tác giảng dạy ứng dụng CNTT của giáo viên
Trang 6Là 1 trong 10 đơn vị được thí điểm trang cấp và ứng dụng triển khai dự án trường học thông minh trong toàn tỉnh
b Khó khăn:
Trong thời gian qua, càng ngày tính đa dạng về trình độ học sinh trong các lớp tại trường THPT Dân tộc nội trú nói riêng và tại các trường THPT trong tỉnh nói chung Trường THPT Dân tộc nội trú Tỉnh có 100% học sinh là người dân tộc thiểu số, ở các xã đặc biệt khó khăn Trước đây phần đa chưa được tiếp xúc với bộ môn tin học, với máy tính Giờ đây các em cũng không có điều kiện tiếp xúc nhiều với máy tính, nên chưa có kỹ năng sử dụng máy tính
Chính vì vậy đề tài này tôi chỉ áp dụng cho việc ôn luyện và thi học sinh giỏi môn tin học tại các trường phổ thông
3 Một số kiến thức cơ bản về chuỗi (String) trong ngôn ngữ lập trình C/C++.
3.1 Tổng quan về chuỗi (String) trong C/C++
C++ bao gồm 2 kiểu biểu diễn chuỗi dưới đây:
- Chuỗi ký tự C-Style
- Lớp String được giới thiệu trong C/C++ chuẩn
3.2 Chuỗi Ký Tự C-Style
Chuỗi ký tự C-Style có nguồn gốc trong ngôn ngữ C và tiếp tục được hỗ trợ trong C++ Bản chất chuỗi này là một mảng các ký tự một chiều được kết thúc
bằng ký tự null '\0' Vì vậy chuỗi null kết thúc chứa các ký tự bao gồm chuỗi theo
sau đó là một null
Ví dụ khai báo và khởi tạo dưới đây sẽ tạo một chuỗi bao gồm từ Hello Để giữ ký tự null ở cuối mảng, kích thước của mảng ký tự chứa chuỗi phải nhiều hơn số lượng các ký tự trong từ khóa "Hello":
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
Nếu thực hiện đúng theo quy tắc khởi tạo, bạn có thể viết lệnh trên như sau:
char greeting[] = "Hello";
Dưới đây là phần biểu diễn bộ nhớ cho chuỗi ở trên trong C/C++:
Trong thực tế, bạn không đặt ký tự null tại vị trí cuối cùng của hằng chuỗi (string constant) Bộ biên dịch C tự động thêm '\0' vào vị trí cuối cùng của chuỗi khi nó khởi tạo chuỗi
3.3 Kiểu chuỗi (String) trong thư viện STL của C++
3.3.1 Các phương thức, phép toán tiện ích của kiểu chuỗi (String) trong C/C++
Thư viện chuẩn STL (Standard Template Library) cung cấp kiểu String Các chỉ thị #include cần khai báo để sử dụng string:
Trang 7#include <string>
using std::string;
//using namespace std;
Kiểu string của STL hỗ trợ các nhóm phương thức và phép toán tiện ích sau đây
* Các phép toán và phương thức cơ bản
- Các toán tử +, += dùng để ghép hai chuỗi và cũng để ghép một ký tự vào chuỗi;
- Các phép so sánh theo thứ tự từ điển: == (bằng nhau), != (khác nhau), > (lớn hơn), >= (lớn hơn hay bằng), < (nhỏ hơn), <= (nhỏ hơn hay bằng);
- Hàm length() và phép lấy chỉ số [] để duyệt từng ký tự của chuỗi: nếu s là biến kiểu string thì s[i] là ký tự thứ i của s với 0≤i<s.length() 0≤i<s.length();
- Phép gán = dùng để gán biến kiểu string bằng một chuỗi, hoặc bằng string khác, chẳng hạn: string s="ABCDEF"; hay s1=s2; mà không cần copy xâu
Những constructor thường sử dụng nhất:
string();
string(const char *str); // char* là kiểu dữ liệu xâu của C
string(const string & str);
- Có thể dùng toán tử << với cout để xuất một chuỗi ra màn hình hoặc dùng toán tử >> với cin để nhập một chuỗi ký tự đến khi gặp một khoảng trống thì dừng
char st[]="ABCDEF";
string s;
s="XYZ";
cout << s << endl;
s=st;
cout << s.length() << " : " << s << endl;
String thực chất là một vector<char> có bổ sung thêm một số hàm và thuộc tính, do đó, nó có toàn bộ các tính chất của 1 vector, như hàm size(), push_back(), toán tử [], …
Các hàm từ vector:
v.size(): Số lượng phần tử
v.empty(): Trả về 1 nếu chuỗi rỗng, 0 nếu ngược lại
v.max_size(): Trả về số lượng phần tử tối đa đã được cấp phát
v1 == v2: Trả về 1 nếu hai chuỗi giống nhau
v1 != v2: Trả về 1 nếu hai chuỗi khác nhau
v.begin(): Trả về iterator đầu tiên của chuỗi
v.end(): Trả về iterator cuối cùng của chuỗi (trỏ vào sau kí tự cuối cùng)
v.front(): Trả về phần tử đầu tiên của chuỗi
v.back(): Trả về phần tử cuối cùng của chuỗi
v1.swap(v2): Hoán đổi 2 chuỗi với nhau (giống việc hoán đổi giá trị của 2 biến)
Trang 8#include <iostream>
#include <conio.h>
#include <string>
using namespace std;
int main()
{
string s = "Hello string"; // Khai báo biến kiểu string
cout << "Noi dung string: " << s << endl; // In nôi dung string ra màn hình cout << "Chieu dai cua string: " << s.size() << endl;
// Chiều dài
cout << "Ky tu 0: " << s[0] << endl; // In ký tự đầu tiên của xâu
cout << "Ky tu 1: " << s[1] << endl; // In ký tự thứ 2
cout << "Ky tu 2: " << s[2] << endl; // In ký tự thứ 3
getchar();
return 0;
}
Nhập một string trên 1 dòng (chú ý cin sẽ chỉ đọc đến dấu cách hoặc xuống dòng đầu tiên): istream& getline ( istream& in, string& str, char delimiter = ‘\n’);
Đọc 1 dòng văn bản từ istream in (có thể là file hay đối tượng chuẩn cin) từng ký tự đến khi ký tự delimiter được nhập vào (mặc định là \n)
// getline with strings
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string str;
short age;
cout << "Please enter full name and age"<< endl;
getline( cin, str) >> age;
cout << "Thank you " << str << "!\n";
return 0;
}
3.3.2 Các phương thức chèn, xóa, lấy chuỗi con:
Phương thức substr(int pos, int nchar) trích ra chuỗi con của một chuỗi cho trước, ví dụ str.substr(2,4) trả về chuỗi con gồm 4 ký tự của chuỗi str kể từ ký tự ở
vị trí thứ 2 (ký tự đầu tiên của chuỗi ở vị trí 0)
//get substring
#include <iostream>
#include <string>
#include <conio.h>
using namespace std;
Trang 9int main ()
{
string s="ConCho chay qua rao";
cout << s.substr(2,4) << endl;
// cout << new string(str.begin()+2, str.begin()+2+4);
getchar();
return 0;
}
Phương thức insert() chèn thêm ký tự hay chuỗi vào một vị trí nào đó của chuỗi str cho trước Có nhiều cách dùng phương thức này:
str.insert(int pos, char* s); chèn s (mảng ký tự kết thúc \0) vào vị trí pos của str; str.insert(int pos, string s); chèn chuỗi s (kiểu string) vào vị trí pos của chuỗi str; str.insert(int pos, int n, int ch); chèn n lần ký tự ch vào vị trí pos của chuỗi str; // inserting into a string
#include <iostream>
#include <string>
#include <conio.h>
using namespace std;
int main ()
{
string str="day la xau thu";
string istr = "them";
str.insert(8, istr);
cout << str << endl;
getchar();
return 0;
}
Phương thức str.erase(int pos, int n) xóa n ký tự của chuỗi str kể từ vị trí pos; nếu không quy định giá trị n thì tất cả các ký tự của str từ vị trí pos trở đi
sẽ bị xóa
// erase from a string
#include <iostream>
#include <string>
#include <conio.h>
using namespace std;
int main ()
{
string str="day cung la xau thu";
str.erase(0, 3); // " cung la xau thu"
cout << str << endl;
str.erase(6, 2);
cout << str << endl; // " cung xau thu"
getchar();
Trang 10return 0;
}
3.3.3 Phương thức so sánh
Bạn có thể đơn giản là sử dụng những toán tử quan hệ (==, !=, <, <=, >=) được định nghĩa sẵn Tuy nhiên, nếu muốn so sánh một phần của một chuỗi thì sẽ cần sử dụng phương thức compare():
int compare ( const string& str ) const;
int compare ( const char* s ) const;
int compare ( size_t pos1, size_t n1, const string& str ) const;
int compare ( size_t pos1, size_t n1, const char* s) const;
int compare ( size_t pos1, size_t n1, const string& str, size_t pos2, size_t n2 ) const;
int compare ( size_t pos1, size_t n1, const char* s, size_t n2) const;
Hàm trả về 0 khi hai chuỗi bằng nhau và lớn hơn hoặc nhỏ hơn 0 cho trường hợp khác Ví dụ:
// comparing apples with apples
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string str1 ("green apple");
string str2 ("red apple");
if (str1.compare(str2) != 0)
cout << str1 << " is not " << str2 << "\n";
if (str1.compare(6,5,"apple") == 0)
cout << "still, " << str1 << " is an apple\n";
if (str2.compare(str2.size()-5,5,"apple") == 0)
cout << "and " << str2 << " is also an apple\n";
if (str1.compare(6,5,str2,4,5) == 0)
cout << "therefore, both are apples\n";
return 0;
}
3.3.4 Các phương thức tìm kiếm và thay thế
Phương thức find() tìm kiếm xem một ký tự hay một chuỗi nào đó có xuất hiện trong một chuỗi str cho trước hay không Có nhiều cách dùng phương thức này:
str.find(int ch, int pos = 0); tìm ký tự ch kể từ vị trí pos đến cuối chuỗi str
str.find(char *s, int pos = 0); tìm s (mảng ký tự kết thúc ‘\0’) kể từ vị trí pos đến cuối
str.find(string& s, int pos = 0); tìm chuỗi s kể từ vị trí pos đến cuối chuỗi.