Tải bản đầy đủ (.pdf) (11 trang)

C# và các lớp cơ sở Xử lý chuỗi – Phần 1 potx

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 (131.23 KB, 11 trang )

C# và các lớp cơ sở
Xử lý chuỗi – Phần 1


Qua chương 2, ta đã xem xét về chuỗi và thấy rằng từ khoá String trong C#
thực sự tham khảo lớp cơ sở system.String. System.string là lớp rất linh hoạt
và mạnh , không phải chỉ là lớp có liên quan đến chuỗi trong .NET. trong
phần này ta sẽ xem lại những đặc tính của System.String, sau đó sử dụng
chuỗi để ứng dụng trong môt số lớp .NET - cụ thể là lớp System.Text và
namespace System.Text.RegularExpressions .
 Xây dựng chuỗi - nếu ta hay lặp lại việc thay đổi trên 1 chuỗi , ví dụ
để định 1 độ dài cho chuỗi trước khi trình bày nó hoặc truyền nó đến vài
phương thức hoặc phần mềm,lớp chuỗi có thể không đủ khả năng để
làm.trong tình huống này, 1 lớp khác , System.Text.StringBuilder thích hợp
hơn, bởi vì nó được thiết kế để làm trong các tình huống này.
 Các biểu thức định dạng - ta sẽ xem xét kĩ hơn những biểu thức định
dạng sử dụng Console.Writeline(). những biểu thức định dạng này sử dụng
vài interface. IFormatProvider và IFormattable,bằng việc sử dụng các
interface này trong lớp riêng , ta có thể định nghĩa những chuỗi định dạng
riêng để console.Writeline() và những lớp quen thuộc sẽ trình bày giá trị
trong lớp của ta theo bất cứ cách nào mà ta chỉ định.
 Biểu thức chính quy ( regular expressions )- .NET cũng đưa ra một
số lớp phức tạp mà đưọc dùng khi ta cần xác định hoặc trích ra chuỗi con
thoả mãn 1 điều kiện phức tạp từ 1 chuỗi dài.ví dụ như cần tìm tất cả các lần
xuất hiện của 1 kí tự hay 1 tập kí tự được lặp lại.hoặc cần tìm tất cả các từ
bắt đầu với 's' và chứa ít nhất 1 kí tự 'n'.mặc dù ta có thể viết phương thức để
làm điều này chỉ bằng việc dùng lớp chuỗi ,nhựng nó rất cồng kềnh. thay
vào đó , ta có thể dùng 1 vài lớp trong System.Text.RegularExpressions mà
đưọc thiết kế để thực thi các quy trình này.
System.String
Trước khi kiểm tra các lớp chuỗi khác, ta sẽ xem lại nhanh những phương


thức trong lớp chuỗi.
System.String là lớp được thiết kế để lưu trữ chuỗi, bao gồm 1 số lớn các
thao tác trên chuỗi.không chỉ thế mà còn bởi vì tầm quan trọng của kiểu dữ
liệu này , C# có từ khoá riêng cho nó và kết hợp với cú pháp để tạo nên cách
dễ dàng trong thao tác chuỗi.
Ta có thể nối chuỗi :
string message1 = "Hello";
message1 += ", There";
string message2 = message1 + "!";
Trích 1 phần chuỗi dùng chỉ mục :
char char4 = message[4]; // trả về 'a'. lưu ý rằng kí tự bắt đầu tính từ chỉ mục
0
các phương thức khác ( sơ lược) :

Phương thức Mục đích
Compare so sánh nội dung của 2 chuỗi
CompareOrdinal
giống compare nhưng không k
ể đến ngôn ngữ bản địa hoặc
văn hoá (as compare but doesn't take culture into account)

Format
định dạng một chuỗi chứa 1 giá trị khác và ch
ỉ định cách
mỗi giá trị nên được định dạng.

IndexOf
vị trí xuất hiện đầu tiên c
ủa 1 chuỗi con hoặc kí tự trong
chuỗi

IndexOfAny
vị trí xuất hiện đầu tiên của bất kì 1 ho
ặc 1 tập kí tự trong
chuỗi
LastIndexOf giống indexof , nhưng tìm lần xuất hiện cuối cùng
LastIndexOfAny
giống indexofAny , nhưng tìm lần xuất hiện cuối cùng
PadLeft
canh phải chuỗi
điền chuỗi bằng cách thêm 1 kí tự được chỉ định lặp lại
vào
đầu chuỗi
PadRigth
canh trái chuỗi
điền chuỗi bằng cách thêm 1 kí tự được chỉ định lặp lại v
ào
cuối chuỗi
Replace
thay th
ế kí tự hay chuỗi con trong chuỗi với 1 kí tự hoặc
chuỗi con khác
Split
chia chuỗi thành 2 mảng chuỗi con ,ngắt bởi sự xu
ất hiện
của một kí tự nào đó
Substring trả về chuỗi con bắt đầu ở một vị trí chỉ định trong chuỗi.
ToLower chuyển chuỗi thành chữ thuờng
ToUpper chuyển chuỗi thành chữ in
Trim bỏ khoảng trắng ở đầu và cuối chuỗi


Xây dựng chuỗi
Chuỗi là 1 lớp mạnh với nhiều phương thức hữu ích , tuy nhiên chuỗi gặp
khó khăn trong việc lặp lại sự thay đổi đến chuỗi ban đầu.nó thực sự là kiểu
dữ liệu không biến đổi, nghĩa là mỗi lần ta khởi động 1 đối tượng chuỗi, thì
đối tượng chuỗi đó không bao giờ được thay đổi.những phương thức hoặc
toán tử mà cập nhật nội dung của chuỗi thực sự là tạo ra một chuỗi mới , sao
chép chuỗi cũ vào nếu cần thiết. ví dụ :
string greetingText = "Hello from all the guys at Wrox Press. ";
greetingText += "We do hope you enjoy this book as much as we enjoyed
writing it.";
Đầu tiên lớp system.String được tạo và khởi tạo giá trị "Hello from all the
people at Wrox Press. "chú ý khoảng trắng sau sau dấu chấm. khi điều này
xảy ra ,thời gian chạy .NET sẽ định vị đủ bộ nhớ trong chuỗi để chứa đoạn
kí tự này( 39 kí tự ).và tạo ra 1 biến greetingText để chuyển đến 1 thể hiện
chuỗi.
Ở dòng tiếp theo , khi ta thêm kí tự vào .ta sẽ tạo ra một chuỗi mới với kích
thước đủ để lưu trữ cả hai đoạn ( 103 kí tự ).đoạn gốc "Hello from all the
people at Wrox Press. ", sẽ được sao chép vào chuỗi mới với đoạn thêm "We
do hope you enjoy this book as much as we enjoyed writing it. " sau đó địa
chỉ trong biến greetingText được cập nhật, vì vậy biến sẽ trỏ đúng đến đối
tượng chuỗi mới.chuỗi cũ không còn được tham chiếu - không có biến nào
truy vào nó- và vì vậy nó sẽ được bộ thu gom rác gỡ bỏ.
Giả sử ta muốn mã hoá chuỗi bằng cách thay đổi từng kí tự với 1 kí tự
ASCII. điều này sẽ trả vế chuỗi : "Ifmmp gspn bmm uif hvst bu Xspy Qsftt.
Xf ep ipqf zpv fokpz uijt cppl bt nvdi bt xf fokpzfe xsjujoh ju." có nhiều
cách làm điều này nhưng cách đơn giản nhất là dùng phương thức
String.replace() mà thay thế chuỗi con này bằng chuỗi con khác, dùng
Replace() ta viết đoạn mã mã hoá như sau :
string greetingText = "Hello from all the guys at Wrox Press. ";
greetingText += "We do hope you enjoy this book as much as we enjoyed

writing it.";
for(int i = (int)'z'; i>=(int)'a' ; i )
{
char old = (char)i;
char new = (char)(i+1);
greetingText = greetingText.Replace(old, new);
}
for(int i = (int)'Z'; i>=(int)'A' ; i )
{
char old = (char)i;
char new = (char)(i+1);
greetingText = greetingText.Replace(old, new);
}
Console.WriteLine("Encoded:\n" + greetingText);
Vậy cần bao nhiêu vùng nhớ làm điều này? Replace() làm việc theo cách
thông minh, để mở rộng nó sẽ không tạo ra một chuỗi mới trừ khi nó thực sự
phải thay đổi chuỗi cũ.chuỗi gốc có 23 kí tự chữ thường khác nhau và 3 kí tự
in khác nhau,Replace() sẽ định vị 1 chuỗi mới tổng cộng 26 lần,mỗi chuỗi
mới lưu trữ 103 kí tự.nghĩa là kết quả quy trình mã hoá sẽ là đối tượng chuỗi
có khả năng lưu trữ kết hợp tổng cộng 2678 kí tự bây giờ đang nằm trong
heap để được thu dọn.Rõ ràng nếu ta sử dụng chuỗi để làm điều này, ứng
dụng của ta sẽ chạy không tốt.
Để giải quyết Microsoft cung cấp lớp System.Text.StringBuilder . lớp
System.Text.StringBuilder không mạnh như lớp chuỗi tính theo thuật ngữ là
số phương thức nó có .tiến trình mà ta có thể làm trên Stringbuilder được
giới hạn thành thay thế hoặc mở rộng hoặc bỏ đoạn từ chuỗi .tuy nhiên nó
làm việc theo cách hiệu quả hơn.
bất cứ nơi nào ta xây dựng chuỗi , chỉ đủ vùng nhớ được định vị để giữ
chuỗi,Stringbuidler sẽ định vị vùng nhớ nhiều hơn cần.ta có thể chỉ định
vùng nhớ được định vị , nếu không , thì số mặc định tuy thuộc vào kích cỡ

của chuỗi mà StringBuilder được khởi động cùng .nó có 2 thuộc tính chính:
Length - độ dài của chuỗi thực sự chứa
Capacity - độ daì chuỗi mà nó chỉ định đủ vùng nhớ để lưu trữ.
Bất kì cập nhật nào đến chuỗi sẽ được làm trong khối vùng nhớ này,như là
viết thêm chuỗi con hoặc thay thế các kí tự riêng trong chuỗi rất tốt.Việc gỡ
bỏ hoặc chèn chuỗi con vẫn không tốt, bởi vì những phần theo sau chuỗi
phải bị di chuyển.chỉ nếu ta thực thi vài thao tác mà tăng dung lượng chuỗi
sẽ tạo ra vùng nhớ mới cần được định vị và toàn bộ chuỗi được chứa có thể
được di chuyển.vào lúc viết ,Microsoft không cho biết làm cách nào để dung
lượng thêm được thêm vào, nhưng từ kinh nghiệm cho thấy StringBuilder
xuất hiện với dung lượng gấp đôi của nó nếu nó thăm dò thấy dung lương bị
vượt quá và không có giá trị mới của dung lương được thiết đặt rõ ràng.
Ví dụ , nếu ta sử dụng đối tượng StringBuilder để tạo ra chuỗi chào đón gốc,
ta viết :
StringBuilder greetingBuilder =
new StringBuilder("Hello from all the guys at Wrox Press. ", 150);
greetingBuilder.Append("We do hope you enjoy this book as much as we
enjoyed
writing it");
Trong mã này . ta thiết lập dung lương khởi tạo là 150 cho StringBuilder. nó
luôn là ý tưởng hay để thiết lập dung lượng mà bao phủ độ dài lớn nhất của
chuỗi , để bảo đảm String builder không cần tái định vị bởi vì dung lượng
của nó lớn .vì vậy ta có thể thiết lập 1 số int cho dung lượng, mặc dù nếu ta
cố định vị vượt quá 2 tỷ ký tự hệ thống sẽ cảnh báo.
khi mã trên thực thi , đầu tiên ta tạo ra 1 đối tượng StringBuilder khởi tạo
như sau:
Khi gọi phương thức append() ,đoạn còn lại đuợc đặt trong khoảng trống,
không cần định vị thêm vùng nhớ.tuy nhiên khả năng thực sự của
StringBuilder chỉ thấy rõ khi lặp lại việc thay thế đoạn. ví dụ, nếu ta cố mã
hoá đoạn văn bản theo cách trên ,ta có thể mã hoá toàn bộ mà không cần

định vị thêm bất kì vùng nhớ nào nữa :
StringBuilder greetingBuilder =
new StringBuilder("Hello from all the guys at Wrox Press. ", 150);
greetingBuilder.Append("We do hope you enjoy this book as much as we
enjoyed
writing it");
for(int i = (int)'z'; i>=(int)'a' ; i )
{
char old = (char)i;
char new = (char)(i+1);
greetingBuilder = greetingBuilder.Replace(old, new);
}
for(int i = (int)'Z'; i>=(int)'A' ; i )
{
char old = (char)i;
char new = (char)(i+1);
greetingBuilder = greetingBuilder.Replace(old, new);
}
Console.WriteLine("Encoded:\n" + greetingBuilder.ToString());
Đoạn mã này dùng phương thức StringBuilder.Replace() mà giống như
String.Replace() nhưng không có sao chép chuỗi trong lúc làm.tổng vùng
nhớ được định vị để giữ chuỗi trong đoạn mã trên là 150 cho người xây
dựng, cũng như vùng nhớ chỉ định trong suốt việc thao tác chuỗi thi hành
bên trong trong câu lệnh cuối Console.Writeline()
thông thường , ta sử dụng StringBuilder để thi hành bất kì thao tác của
chuỗi, và String để lưu trữ hoặc trình bày kết quả cuối cùng.

×