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

cấu trúc dữ liệu chương 3

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 (310 KB, 24 trang )

Chương 3
Chuỗi

Chương 3. Chuỗi

2006

Nguyễn Trung Trực - Khoa CNTT 1


Nội dung
Ðịnh nghĩa chuỗi.
™ Các cách phân chia chuỗi.
™ Các hàm và thủ tục.
™ Tìm kiếm chuỗi con.
™

f Giải

thuật Brute-Force
f Giải thuật Knuth-Morris-Pratt
f Giải thuật Boyer-Moore

Chương 3. Chuỗi

2006

Nguyễn Trung Trực - Khoa CNTT 2


Các định nghĩa


™

Định nghĩa chuỗi
f Chuỗi

(string) là một dãy các ký tự được
chứa trong một vùng liên tục của bộ nhớ.
Các ký tự này có thể là các ký tự chữ, ký tự
số hoặc các ký tự đặc biệt.

™

Các khái niệm
f Chiều

dài (length) của chuỗi là số ký tự của

chuỗi.
f Chuỗi rỗng (null string) là chuỗi có chiều dài
bằng 0, ký hiệu là ‘’.
f Chuỗi con (substring) là một thành phần bao
gồm các ký tự liên tiếp nhau của chuỗi.
Chương 3. Chuỗi

2006

Nguyễn Trung Trực - Khoa CNTT 3


Các cách phân chia chuỗi

™

Sử dụng ký tự đặc biệt
f Sử

dụng các ký tự đặc biệt (không là ký tự
của chuỗi) để phân tách các chuỗi con.
f Chiều dài của các chuỗi con có thể khác
nhau.
f Truy xuất tuần tự từ đầu chuỗi để tìm kiếm
một chuỗi con.
f Thời gian truy xuất một chuỗi con là chậm.
800
H O A N G
Chương 3. Chuỗi

806
A N H

810

817

P H U O N G
2006

L O C

Nguyễn Trung Trực - Khoa CNTT 4



Các cách phân chia chuỗi
™

Sử dụng chiều dài chuỗi con cố định
f Sử

dụng các ký đệm vào mỗi chuỗi con.
f Chiều dài của các chuỗi con bằng nhau.
f Truy xuất trực tiếp theo công thức tính địa
chỉ để tìm kiếm một chuỗi con.
f Thời gian truy xuất một chuỗi con là nhanh.

800

H

807

O A

N

Chương 3. Chuỗi

G

A

814


N

H

P

821

H

U

2006

O

N

G

L

O

C

Nguyễn Trung Trực - Khoa CNTT 5



Các cách phân chia chuỗi
™

Sử dụng con trỏ
f Sử

dụng các con trỏ chỉ vào các chuỗi con.
f Chiều dài của các chuỗi con có thể khác
nhau.
f Truy xuất trực tiếp theo con trỏ để tìm kiếm
một chuỗi con.
f Thời gian truy xuất một chuỗi con là nhanh.

Chương 3. Chuỗi

2006

Nguyễn Trung Trực - Khoa CNTT 6


Các cách phân chia chuỗi
™

Sử dụng con trỏ đầu
last
H O A N G A N H P H U O N G L O C
pointer

1


800

2

805

3
4

808
814
ai = pointer[i]
bi = pointer[i+1] - 1 với i < n
= last

Chương 3. Chuỗi

với i = n
2006

Nguyễn Trung Trực - Khoa CNTT 7


Các cách phân chia chuỗi
™

Sử dụng con trỏ cuối
first
H O A N G A N H P H U O N G L O C
pointer


1

804

2

807

3
4

813
816
ai = first
= pointer[i-1] +1 với i = 1
bi = pointer[i]

Chương 3. Chuỗi

với i > 1
2006

Nguyễn Trung Trực - Khoa CNTT 8


Các hàm và thủ tục
™

Các hàm

f length(s):
y

Ví dụ: length(‘abc’) → 3

f concat(s1,

…, sn.
y

trả về số ký tự của chuỗi s.
s2, …, sn): kết nối các chuỗi s1, s2,

Ví dụ: concat(‘abc’,’12’) → ‘abc12’

f copy(s,

m, n): lấy chuỗi con của chuỗi s gồm
n ký tự kể từ ký tự thứ m.
y

Ví dụ: copy(‘abcde’,3,2) → ‘cd’

f pos(s1,

s2): trả về vị trí tìm thấy chuỗi s1 trong
chuỗi s2.
y

Ví dụ: pos(‘bc’,’abcd’) → 2


Chương 3. Chuỗi

2006

Nguyễn Trung Trực - Khoa CNTT 9


Các hàm và thủ tục
™

Các thủ tục
f val(s,

x, n): biến đổi chuỗi s thành giá trị số
và gán cho x; n được gán số 0 nếu biến đổi
đúng.
y
y

Ví dụ: val(‘123.45’, x, n) sẽ gán số 123.45 cho x.
Ví dụ: val(’12a’, x, n) → x không xác định và n là
3.

f str(x,

s): biến đổi giá trị số x thành giá trị
chuỗi và gán cho s.
y


Ví dụ: str(123.45, s) sẽ gán chuỗi ‘123.45’ cho s.

Chương 3. Chuỗi

2006

Nguyễn Trung Trực - Khoa CNTT 10


Các hàm và thủ tục
™

Các thủ tục
f delete(s,

m, n): xóa n ký tự trong chuỗi s bắt
đầu từ vị trí m.
y

Ví dụ: chuỗi s là ‘abcde’ thì delete(s,2,3) sẽ gán
chuỗi ‘ae’ cho s.

f insert(s1,

s2, m): xen chuỗi s1 vào trong chuỗi
s2 tại vị trí m.
y

Ví dụ: chuỗi s là ‘abc’ thì insert(‘12’,s,2) sẽ gán
chuỗi ‘a12bc’ cho s.


Chương 3. Chuỗi

2006

Nguyễn Trung Trực - Khoa CNTT 11


Tìm kiếm chuỗi con
™

Tìm chuỗi p có chiều dài là m trong chuỗi a
có chiều dài là n. Có hai trường hợp tìm
kiếm:
f Tìm

thấy chuỗi p trong chuỗi a: kết quả trả về
là vị trí của ký tự đầu tiên của lần tìm thấy
đầu tiên.
f Không tìm thấy chuỗi p trong chuỗi a: kết
quả trả về là 0.
™

Các giải thuật
f Giải

thuật Brute-Force
f Giải thuật Knuth-Morris-Pratt
f Giải thuật Boyer-Moore
Chương 3. Chuỗi


2006

Nguyễn Trung Trực - Khoa CNTT 12


Giải thuật Brute-Force
™

Phương pháp
fỞ

vị trí ký tự a[i], so sánh các ký tự tương
ứng từ trái qua phải: p[1] với a[i], p[2] với
a[i+1], …, p[m] với a[i+m-1].
a

x x x x x x x x x x
i

p

x x x x x x
1

Chương 3. Chuỗi

2006

Nguyễn Trung Trực - Khoa CNTT 13



Giải thuật Brute-Force
function Brute_Force (p, a: string): integer;
var i, j, m, n: integer;
begin
m := length(p); n := length(a); i := 1; j := 1;
repeat
if a[i] = p[j] then begin
i := i + 1; j := j + 1
end
else begin
i := i - j + 1; j := 1
end
until (j > m) or (i > n);
if j > m then Brute_Force := i - m
else Brute_Force := 0
end;
Lệnh gọi: position := Brute_Force (p, a);
Chương 3. Chuỗi

2006

Nguyễn Trung Trực - Khoa CNTT 14


Giải thuật Knuth-Morris-Pratt
™

Phương pháp

f Trong

giải thuật Brute-Force, khi so sánh để
p[j] khác với a[i] thì đã có j-1 ký tự đầu tiên
của chuỗi p trùng với các ký tự tương ứng
của chuỗi a.
f Do đó, không cần phải cho i quay trở về mà
vẫn cho i tăng tiếp tục (thay thế i := i - j + 2
bởi i := i + 1) và gán cho j một giá trị thích
hợp. Mảng next[j] xác định các giá trị thích
hợp gán cho j.

Chương 3. Chuỗi

2006

Nguyễn Trung Trực - Khoa CNTT 15


Giải thuật Knuth-Morris-Pratt
Xét chuỗi p = ‘10100111’
j next[j]
2 1
1 0 1 0
1 0 1
3 1
1 0 1 0
1 0
4 2
1 0 1 0

1 0
5 3
1 0 1 0
1 0
6 1
1 0 1 0
7
8

2
2

Chương 3. Chuỗi

0
0
0
1
0
1
0
1
0

1
0
1
0
1
0

1
0
1
1
1 0 1 0 0 1
1
1 0 1 0 0 1

1
1
1
0
1
0
1
0
1
0
1
0
1
1

1
1
1
1
1
1
1

1
1
1
1
1
1
0

1
1 1
1 1
1 1
0 0 1 1 1
0 0 1 1 1
1 0 0 1 1 1
2006

Nguyễn Trung Trực - Khoa CNTT 16


Giải thuật Knuth-Morris-Pratt
function KMP (p, a: string): integer;
var i, j, m, n: integer;
next: array [1..255] of integer;
procedure Init_Next;
begin
i := 1; j := 0; next[1] := 0;
repeat
if (j = 0) and (p[i] = p[j]) then
begin

i := i + 1; j := j + 1; next[i] := j
end
else j := next[j]
until i >= m;
end;
Chương 3. Chuỗi

2006

Nguyễn Trung Trực - Khoa CNTT 17


Giải thuật Knuth-Morris-Pratt
begin {KMP}
m := length(p); n := length(a); Init_Next;
i := 1; j := 1;
repeat
if (j = 0) or (a[i] = p[j]) then
begin
i := i + 1; j := j + 1
end
else j := next[j]
end
until (j > m) or (i > n);
if j > m then KMP := i - m
else KMP := 0
end;
Lệnh gọi: position := KMP (p, a);
Chương 3. Chuỗi


2006

Nguyễn Trung Trực - Khoa CNTT 18


Giải thuật Knuth-Morris-Pratt cải tiến

Chương 3. Chuỗi

1

0

1

0

0

1

1

1

1

0

1


0

0

1

1

1

2006

Nguyễn Trung Trực - Khoa CNTT 19


Giải thuật Knuth-Morris-Pratt cải tiến
procedure Init_Next;
begin
i := 1; j := 0; next[1] := 0;
repeat
if (j = 0) and (p[i] = p[j]) then
begin
i := i + 1; j := j + 1;
if p[j] <> p[i] then next[i] := j
else next[i] := next[j]
end
else j := next[j]
until i >= m;
end;

Chương 3. Chuỗi

2006

Nguyễn Trung Trực - Khoa CNTT 20


Giải thuật Boyer-Moore
™

Phương pháp
f Xét

chuỗi p từ phải qua trái trong khi so sánh
chuỗi p với chuỗi a.
f Next[j] là số vị trí ký tự mà chuỗi p di chuyển
qua phải đối với chuỗi p1 (bản sao của chuỗi
p) để có được vị trí khác nhau ở ký tự thứ j
kể từ phải qua trái của chuỗi p.
f Mảng skip[c] xác định vị trí mới của i khi có
sự so sánh khác nhau.
y
y

skip[c] = m nếu c không là ký tự của chuỗi p.
skip[c] = m-j nếu c là ký tự thứ j của chuỗi p.

Chương 3. Chuỗi

2006


Nguyễn Trung Trực - Khoa CNTT 21


Giải thuật Boyer-Moore
Xét chuỗi p = ‘10110101’
j next[j]
2 1
1 0 1 1 0 1 0 1
1 0 1 1
3 7
1 0 1 1 0 1 0 1
1
4 2
1 0 1 1 0 1 0 1
1 0 1 1 0 1
5 5
1 0 1 1 0 1 0 1
1 0 1
6 5
1 0 1 1 0 1 0 1
1 0 1
7 5
1 0 1 1 0 1 0 1
1 0 1
8 5
1 0 1 1 0 1 0 1
1 0 1
Chương 3. Chuỗi


0 1 0 1
0 1 1 0 1 0 1
0 1
1 0 1 0 1
1 0 1 0 1
1 0 1 0 1
1 0 1 0 1
2006

Nguyễn Trung Trực - Khoa CNTT 22


Giải thuật Boyer-Moore
function Boyer_Moore (p, a: string): integer;
var i, j, m, n: integer;
skip: array [1..255] of integer;
procedure Init_Skip;
var i: 1..255; j: integer;
begin
for i := 1 to 255 do skip[i] := m;
if skip[ord(p[j])] = m then skip[ord(p[j])] := m-j;
end;
begin
m := length(p); n := length(a); Init_Skip;
i := m; j := m;
Chương 3. Chuỗi

2006

Nguyễn Trung Trực - Khoa CNTT 23



Giải thuật Boyer-Moore
repeat
if a[i] = p[j] then
begin
i := i - 1; j := j - 1
end
else
begin
if m - j + 1 > skip[ord(a[i])] then i := i+m-j+1
else i := i + skip[(ord(a[i])];
j := m
end
until (j < 1) or (i > n);
if j < 1 then Boyer_Moore := i + 1
else Boyer_Moore := 0
end;
Chương 3. Chuỗi

2006

Nguyễn Trung Trực - Khoa CNTT 24



×