Giả sử chúng ta được cung cấp hai chuỗi. Chuỗi đầu tiên có độ dài lớn hơn chuỗi thứ hai, và chúng ta phải kiểm tra xem các chuỗi con từ chuỗi đầu tiên có khớp chính xác với chuỗi thứ hai hay khác biệt ở một vị trí. Chúng ta trả về các chỉ số của chuỗi đầu tiên, nơi các chuỗi con có thể khớp với chuỗi thứ hai bắt đầu.
Ví dụ, nếu đầu vào là string1 = 'tpoint', string2 = 'pi', thì đầu ra sẽ là 1 2.
Các chuỗi con từ chuỗi đầu tiên khớp với chuỗi thứ hai hoặc khác một vị trí tại chỉ số 1 và 2 lần lượt là 'po' và 'oi'.
Thuật toán giải quyết
Để giải quyết bài toán này, chúng ta thực hiện các bước sau:
- Định nghĩa hàm
search()nhận vàostring1vàstring2:- Ghép chuỗi:
str_cat := string1 + string2 - Khởi tạo mảng Z
z_listkích thướcstr_catvới giá trị 0 - Thiết lập
z_list[0] := độ dài của str_cat - Khởi tạo
right := 0,left := 0 - Duyệt
itừ 1 đến độ dàistr_cat:- Nếu
i > right: mở rộng thủ công từ vị tríi - Ngược lại: tận dụng thông tin đã tính toán trong khoảng
[left, right] - Cập nhật
z_list[i] := min(độ dài string1, z_list[i])
- Nếu
- Trả về phần của
z_listtừ chỉ sốđộ dài string1đến cuối
- Ghép chuỗi:
- Tính
fwd := search(str2, str1)(chuỗi thứ hai so với chuỗi thứ nhất) - Tính
bwrd := search(đảo ngược str2, đảo ngược str1)rồi đảo ngược kết quả - Duyệt các vị trí bắt đầu có thể của chuỗi con trong
str1:- Nếu
fwd[i] + bwrd[i + len(str2) - 1] >= len(str2) - 1thì thêm chỉ sốivào kết quả
- Nếu
- Trả về danh sách chỉ số hoặc
Falsenếu không tìm thấy
Ví dụ minh họa
def search(string1, string2):
str_cat = string1 + string2
z_list = [0] * len(str_cat)
z_list[0] = len(str_cat)
right = 0
left = 0
for i in range(1, len(str_cat)):
if i > right:
j = 0
while j + i < len(str_cat) and str_cat[j] == str_cat[j+i]:
j += 1
z_list[i] = j
if j > 0:
left = i
right = i + j - 1
else:
k = i - left
r_len = right - i + 1
if z_list[k] < r_len:
z_list[i] = z_list[k]
else:
m = right + 1
while m < len(str_cat) and str_cat[m] == str_cat[m - i]:
m += 1
z_list[i] = m - i
left = i
right = m - 1
z_list[i] = min(len(string1), z_list[i])
return z_list[len(string1):]
def solve(str1, str2):
fwd = search(str2, str1)
bwrd = search(str2[::-1], str1[::-1])
bwrd.reverse()
idx = []
for i in range(len(str1) - len(str2) + 1):
if fwd[i] + bwrd[i + len(str2) - 1] >= len(str2) - 1:
idx.append(str(i))
if len(idx) == 0:
return False
else:
return " ".join(idx)
print(solve('tpoint', 'pi'))
Đầu vào
'tpoint', 'pi'
Đầu ra
1 2