1. Trang chủ
  2. » Công Nghệ Thông Tin

Công cụ xử lý chuỗi

5 649 2
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Công cụ xử lý chuỗi
Tác giả Ngô Minh Đức
Trường học University of Information Technology
Chuyên ngành Computer Science
Thể loại bài viết
Thành phố Hồ Chí Minh
Định dạng
Số trang 5
Dung lượng 41,5 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Công cụ xử lý chuỗi

Trang 1

Null-terminated String và Strings Unit - những công cụ xử lý chuỗi hiệu

quả của Pascal

Ngô Minh Đức

- Null-terminated Strings là kiểu chuỗi có giới hạn lên tới 65535 ký tự, các hàm xử lý trên

kiểu chuỗi này từ lâu đã được Pascal cung cấp trong Strings Unit và được hướng dẫn sử dụng trong phần help của Pascal

- Null-terminated Strings được khai báo bằng một mảng ký tự:

array[0 X] of char

trong đó X là một số nguyên dương đạt giá trị tối đa là 65534

- Strings Unit: của Pascal cung cấp các hàm xử lý trên Null-terminated Strings Để sử dụng

được Strings Unit ta phải đặt compiler directive {$X} ở chể độ + (mặc định)

- Kiểu PChar: là một kiểu dữ liệu đặc biệt, dùng để xử lý các Null-terminated Strings Thực ra PChar là một kiểu con trỏ được khai báo như sau: type PChar=^Char

nhưng PChar được trang bị một số phép toán đặc biệt

Chúng ta có thể dùng PChar giống kiểu String:

Var P:PChar;

P:='ISM'; {hợp lệ}

Write(P); {in ra chữ 'ISM'}

Write(P[0]) {in ra chữ 'I'}

Write(P[2]) {in ra chữ 'M'}

Tuy nhiên chúng ta có thể sử dụng theo cách khác:

Write(P^); {in ra chữ 'I' }

Write((P+1)^); {in ra chữ 'S'}

Write(P+1); {in ra chữ 'SM' }

Tóm lại: khi bạn khai báo P:='ISM' có nghĩa là con trỏ P đã được chỉ vào chữ 'I', chữ đầu của chuỗi 'ISM' Vì vậy P^ mang giá trị 'I' Cách viết P+1 chính là sự đặc biệt của kiểu PChar, P+1 chính là con trỏ trỏ vào chữ 'S' Ngoài ra còn chúng ta thấy cách viết Write(P) trong đó P mang kiểu PChar là hoàn toàn hợp lệ, nó in ra chuỗi mà con trỏ P đang trỏ vào

ký tự đầu tiên Khi ta viết Write(P) thì được 'ISM' còn viết Write(P+1) thì được 'SM'

- Kiểu PChar được trang bị các phép tính sau:

Với P, Q kiểu PChar, I kiểu Word thì:

P + I: trỏ vào ký tự đứng sau ký tự mà P trỏ vào I ký tự

P - I: trỏ vào ký tự đứng trước ký tự mà P trỏ vào I ký tự

P - Q: nếu P và Q trỏ vào hai ký tự của cùng một chuỗi, kết qủa sẽ là khoảng cách giữa hai

ký tự đó Ví dụ trong chuỗi 'ISM', P trỏ vào chữ 'M', Q trỏ vào chữ 'I' thì P-Q=2

Nếu P và Q trỏ vào hai chuỗi khác nhau, kết qủa vô nghĩa

- Phép gán mảng ký tự dạng Null-Terminated Strings (Array[0 X] Of Char) cho kiểu PChar là hợp lệ Ví dụ:

Const Number:Array[0 4] Of Char = ('1','2','3','4','5');

Var P:Pchar;

P:=Number; {hợp lệ}

Trang 2

Write(P); {in ra '12345'}

- Xét một hàm dạng như sau của Strings Unit:

Function StrCopy(Dest, Source: PChar): PChar;

Khi đó bạn có thể dùng kiểu mảng Null-terminated Strings hoặc kiểu PChar cho các tham

số Bạn có thể viết StrCopy(P, 'ISM'); vì 'ISM' sẽ được hiểu là kiểu PChar chứ không phải

là kiểu String của Pascal

- Khi sử dụng các hàm của Strings Unit, chẳng hạn:

Var P:PChar;

StrCopy(P,'Turbó);

Thì khi viết Write(P) sẽ không hiện ra chữ 'Turbó mặc dù khi viết

Write(P^) vẫn in ra chữ 'T' và Write(P+1) vẫn in ra chữ 'urbó

- Với kiểu PChar thì không thể đọc được dữ liệu:

Var P:PChar; F:Text;

Readln(P) hoặc Readln(F,P); {không hợp lệ}

nhưng với kiểu mảng Null-terminated Strings (tức là bắt buộc phải có dạng Array[0 X] of Char) thì đọc được dữ liệu:

var S:array[0 1000] Of Char; F:Text;

Readln(S); hoặc Readln(F,S); {hợp lệ}

- Vì vậy ta thường không khai báo kiểu PChar mà khai báo kiểu mảng Null-terminated Strings:

Var S: array[0 1000] Of Char;

StrCopy(S, 'Turbó);

Đặc biệt trong kiểu mảng Null-terminated Strings thì cách viết Write(S+1) vẫn hợp lệ (in

ra chữ 'urbó)

- Ta không dùng các hàm của Strings Unit như một Function mà hay dùng như Procedure (hợp lệ nhờ khai báo $X+), như sau:

Var S:Array[0 100] Of Char;

Strcopy(S,'Turbó);

Ta viết: StrCat(S,'Pascal') chứ không viết S:=StrCat(S,'Pascal'); {không hợp lệ}

Write(S); {in ra 'Turbo Pascal'}

Các hàm của Strings Unit:

- StrCat: Nối 2 chuỗi

function StrCat(Dest, Source: PChar): PChar;

vd: StrCopy(S,'Turbó);

StrCat(S,'Pascal');

Write(S); {in ra 'Turbo Pascal'}

- StrLCat: Nối một số kí tự của chuỗi này vào chuỗi kia

function StrLCat(Dest, Source:PChar; MaxLen:Word):Pchar;

copy MaxLen-StrLen(Dest) ký tự từ chuỗi Source vào chuỗi Dest

vd: StrCopy(S,'Turbó);

StrLCat(S,'Pascal',7);

Write(S); {in ra 'Turbo P'}

- StrComp: so sánh hai chuỗi

Trang 3

function StrComp(Str1,Str2:PChar):Integer;

Tương tự cách so sánh <, =, >, <=, > của kiểu String thường

Trả về kết qủa:

< 0 nếu Str1

=0 nếu Str1=Str2

>0 nếu Str1>Str2

Phân biệt chữ thường và chữ hoạ Vd: StrComp('Á,'Á)=0 nhưng StrComp('á,'Á)=32

- StrIComp: giống StrComp nhưng không phân biệt chữ thường và chữ hoa

- StrLComp: so sánh một số ký tự của hai chuỗi

function StrLComp(Str1,Str2:PChar; MaxLen:Word):Integer;

vd: StrLComp(S1,S2,5); {so sánh 5 kí tự đầu của hai chuỗi S1, S2}

- StrLIComp: giống StrLComp nhưng không phân biệt chữ thường và chữ hoa

- StrCopy: copy một chuỗi vào chuỗi khác

function StrCopy(Dest, Source:PChar):PChar;

vd: StrCopy(S,'Turbo Pascal');

Write(S); {In ra 'Turbo Pascal'}

- StrECopy: copy một chuỗi vào chuỗi khác và trả về con trỏ trỏ tới vị trí cuối cùng của

chuỗi kết qủa

funtion StrECopy(Dest, Source:PChar):PChar;

vd: var P:PChar; S:Array[0 1000] Of Char;

P:=StrECopy(S,'Turbó);

Write(P-5); {in ra 'Turbó);

hoặc var S:Array[0 1000] Of Char;

StrECopy(StrECopy(StrECopy(S,'Turbó), ' '), 'Pascal');

Write(S); {in ra 'Turbo Pascal'}

- StrLCopy: copy các ký tự của một chuỗi vào chuỗi khác

function StrLCopy(dest, Source: PChar; MaxLen:Word):PChar;

vd: write(StrCopy(S,'Turbo Pascal', 5)); {in ra 'Turbó}

- StrEnd: trả về con trỏ trỏ tới vị trí cuối cùng của chuỗi

function StrEnd(str:PChar):PChar;

- StrNew: Cấp vùng nhớ cho một chuỗi mới trên heap

function StrNew(Str:PChar):PChar;

vd: var P:PChar;

StrCopy(S,'TurboPascal');

P:=StrNew(S);

Lúc này P là con trỏ PChar ứng với chuỗi mới 'Turbo Pascal' vừa được tạo ra (bây giờ 2 chuỗi S và P độc lập nhau nhưng đều có giá trị 'Turbo Pascal')

- StrDispose: Thu hồi lại vùng nhớ của chuỗi vừa được cấp bởi StrNew

function StrDispose(Str:PChar);

vd: P:=StrNew(S);

StrDispose(P); {lúc này P=Nil}

- StrLen: trả về độ dài chuỗi

function StrLen(Str:PChar):Word;

- StrLower: đổi chuỗi thành toàn chữ thường

function StrLower(Str:PChar):PChar;

vd: StrCopy(S,'TuRbó);

Trang 4

StrLower(S);

Write(S); {in ra 'turbó}

- StrUpper: đổi chuỗi thành toàn chữ hoa

function StrUpper(Str:PChar):PChar;

- StrMove: copy một số kí tự từ chuỗi này sang chuỗi khác

function StrMove(Dest, Source: PChar; Count: Word): Pchar;

thay thế (count) kí tự đầu của chuỗi Dest bằng (count) kí tự đầu của chuỗi Source

vd: Write(strMove('Purbó,'Tablé,1)); {in ra 'Turbó}

- StrPas: đổi null-terminated string thành Pascal string

function StrPas(str:PChar):String;

- StrPCopy: đổi Pascal String thành null-terminated String

function StrPCopy(dest:Pchar; Source: String):Pchar;

- StrPos: function StrPos(Str1, Str2:PChar):PChar;

Trả về con trỏ trỏ đến vị trí xuất hiện đầu tiên của chuỗi Str2 trong chuỗi Str1, nếu chuỗi Str2 không xuất hiện trong chuỗi Str1, trả về Nil

- StrScan: function StrScan(Str:Pchar; Chr:Char):PChar;

Trả về con trỏ trỏ đến vị trí xuất hiện đầu tiên của kí tự Chr trong chuỗi Str, nếu kí tự Chr không xuất hiện trong chuỗi Str, trả về Nil

- StrRScan : function StrRScan(Str:Pchar; Chr:Char): PChar;

Trả về con trỏ trỏ đến vị trí xuất hiện cuối cùng của kí tự Chr trong chuỗi Str, nếu kí tự Chr không xuất hiện trong chuỗi Str, trả về Nil

Bài toán áp dụng

Cho một file văn bản text.inp gồm nhiều dòng, mỗi dòng không quá 255 kí tự Một cụm từ

S không qúa 255 kí tự Hãy tìm số lần xuất hiện của cụm từ S trong văn bản

Ta có thể nghĩ đến giải pháp đọc từng dòng của văn bản, sau đó dùng hàm Pos của Pascal

để tìm chuỗi S trong dòng đó Nhưng khi đó xảy ra trường hợp cụm từ S có thể nằm trên hai dòng:

Chẳng hạn: S='Tin học và nhà trường'

Và văn bản là:

Tin học

và nhà trường

Vì vậy chúng ta phải nghĩ tới cách khác Chúng ta có thể tách S thành từng từ để tìm, nhưng sao chúng ta không thử dùng null-terminated strings? Sau đây tôi thử cài đặt chương trình dùng null-terminated string:

Giải pháp đưa ra là: tạo một chuỗi null-terminated string:

var str:array[0 1000] Of Char;

Mỗi lần ta đọc vào chuỗi str một số dòng của văn bản sao cho không lớn hơn sức chứa của str, sau đó sử dụng hàm StrPos để tìm chuỗi S trong str

Sau đó gọi lệnh:

StrCopy(Str,StrEnd(Str)-StrLen(S)+1);

Tiếp tục đọc các dòng văn bản vào Str và lặp lại việc tìm kiếm

+ Dữ liệu: file text.inp

dòng đầu tiên chứa cụm từ S

các dòng tiếp theo chứa nội dung của văn bản

+ Kết qủa: file text.out

gồm một dòng duy nhất chứa số tự nhiên N là số lần xuất hiện của cụm từ S trong văn bản

Trang 5

Chương trình như sau:

Uses Strings;

Const fInput='text.inp';

fOutput='text.out';

maxLen=1000;

lineLen=255;

Var Str:Array[0 maxLen] Of Char;

S:Array[0 lineLen] Of Char;

N:Longint;

Procedure Search;

Var P:PChar;

Begin P:=StrPos(Str,S); While P<>Nil Do Begin N:=N+1; P:=StrPos(P+1,S); End; StrCopy(Str,StrEnd(Str)-StrLen(S)+1);

End;

Procedure Xuly;

Var F:Text;

sLine:array[0 lineLen] Of Char;

Begin Assign(F,fInput); Reset(F); Readln(F,S); n:=0; While Not Eof(F) Do Begin Readln(F,sLine); If (StrLen(Str)+StrLen(sLine))>=maxLen Then

Search; StrCat(Str,sLine); StrCat(Str,' '); End; Search; Close(F);

End;

Procedure Xuat;

Var F:Text;

Begin Assign(F,fOutput); Rewrite(F); Write(F,N); Close(F);

End;

Begin Xuly; Xuat;

End

Ngày đăng: 07/09/2012, 11:40

TỪ KHÓA LIÊN QUAN

w