Chuỗi con chấp nhận được¶
Khái quát về bài toán¶
Bài toán này1 có thể dùng để luyện tập về vòng lặp và một chút đề cập đến việc sắp xếp các phần tử mà có hai thuộc tính.
Yêu cầu¶
Cho hai chuỗi s1 và s2 gồm các ký tự từ a đến z.
Thực hiện xóa một số ký tự trong hai chuỗi và giữ nguyên vị trí tương đối của các ký tự còn lại, nếu hai chuỗi con s nhận được sau khi xóa mà giống nhau thì s được gọi là chuỗi chấp nhận được.
Tìm chuỗi s có thứ tự từ điển lớn nhất.
Input¶
accacca
abcda
Output¶
ca
Giải thích¶
Các chuỗi con chấp nhận được của s1 và s2 là: a, aa, ac, aca, c, ca. Trong đó ca là chuỗi chấp nhận được có thứ tự từ điển lớn nhất.
Cách giải đề xuất¶
Ý tưởng chính¶
Ta không thực hiện xóa ký tự như yêu cầu bài toán, mà chọn ra những ký tự giống nhau theo hướng sau:
- Do yêu cầu là thứ tự từ điển lớn nhất, nên trước hết, ta sắp xếp các ký tự trong cùng một chuỗi theo thứ tự giảm dần từ z về a. Trường hợp ký tự xuất hiện nhiều lần, thì sắp xếp tăng dần theo vị trí xuất hiện.
- Sau khi sắp xếp, thực hiện duyệt các ký tự từ đầu đến cuối để chọn ra những ký tự giống nhau trong cả hai chuỗi mà vẫn đảm bảo vị trí tương đối của chúng.
Các bước thực hiện¶
Bước 1¶
Khởi tạo vector v1
và v2
tương ứng với s1
và s2
, trong đó mỗi phần tử gồm hai thuộc tính là: ký tự và vị trí của ký tự đó trong chuỗi.
Vector v1
0 | 1 | 2 | 3 | 4 | 5 | 6 | |
---|---|---|---|---|---|---|---|
Ký tự | a | c | c | a | c | c | a |
Vị trí | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
Vector v2
0 | 1 | 2 | 3 | 4 | |
---|---|---|---|---|---|
Ký tự | a | b | c | d | a |
Vị trí | 0 | 1 | 2 | 3 | 4 |
Bước 2¶
Sắp xếp mỗi vector theo thứ tự ký tự giảm dần từ z về a. Nếu một ký tự xuất hiện nhiều lần thì sắp xếp theo vị trí tăng dần.
Vector v1
0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|
c | c | c | c | a | a | a |
1 | 2 | 4 | 5 | 0 | 3 | 6 |
Vector v2
0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|
d | c | b | a | a |
3 | 2 | 1 | 0 | 4 |
Để sắp xếp, ta cần tạo hàm compare
hỗ trợ việc so sánh hai phần tử.
Sau đó, ta gọi hàm sort()
của C++ để sắp xếp vector với tham số là hàm compare
vừa viết.
Bước 3¶
- Đặt
res
là vector kết quả, lưu các ký tự giống nhau giữa hai chuỗi theo thứ tự z-a. -
Bước 3.1.
Xác định vị trí có ký tự giống nhau đầu tiên trongv1
vàv2
, đặt vị trí giống nhau này làp1
vàp2
. Đồng thời, nạp ký tự giống nhau này vào vector kết quảres
. -
Bước 3.2.
Choi1
chạy từp1 + 1
đến hết vectorv1
, thực hiện lặp:-
Nếu ký tự
i1
đang xét mà nằm sau ký tựp1
, tức có vị trí trongs1
lớn hơn, thì choi2
chạy từp2 + 1
đến hết vectorv2
, thực hiện lặp:- Nếu ký tự
i2
đang xét mà nằm sau ký tựp2
, tức có vị trí trongs2
lớn hơn, và ký tựi2
giống với ký tựi1
thì:- Ghi nhận vị trí
p1
vàp2
mới, lài1
vài2
đang xét. - Nạp ký tự giống nhau này vào vector
res
.
- Ghi nhận vị trí
- Nếu ký tự
-
Toàn bộ chương trình¶¶
Code đầy đủ được đặt tại GitHub.
-
Bài toán do chủ thớt lấy từ bạn bè hoặc người quen nhưng không còn nhớ chính xác là ai. ↩