Xóa rồi kiểm lại đúng vị trí
Khi xóa `A[i]`, phần tử sau nó chuyển về đúng chỉ số i. Vì vậy nếu vừa xóa vừa tăng i, có thể bỏ qua một phần tử âm đứng ngay sau. Mã sau chỉ tăng i khi **không xóa**:
```python
A = [4, -1, -2, 5]
i = 0
while i < len(A):
if A[i] < 0:
del A[i]
else:
i = i + 1
print(A)
```
Kết quả là `[4, 5]`. Sau khi xóa -1, -2 dồn về cùng vị trí nên được xét ngay lượt kế. Với `A = []`, điều kiện sai từ đầu và chương trình in `[]`. Bài xét danh sách số mẫu, không xóa dữ liệu học viên thật.
Bài luyện
Sau khi xóa phần tử âm tại chỉ số i, vì sao mã trong bài chưa tăng i ngay?
Phần tử tiếp theo vừa chuyển vào vị trí i.
i vẫn tăng ở lượt không xóa.
del thay đổi độ dài và vị trí.
while tiếp tục kiểm điều kiện.
Lời giải
Xóa `A[i]` làm phần tử sau nó dồn vào chỉ số i. Giữ i để xét phần tử mới tại đó, tránh bỏ sót hai số âm liên tiếp.
Bài luyện
Với `A = [4, -1, -2, 5]`, mã xóa số âm trong bài in gì?
-2 cũng được xét và xóa.
Hai số âm bị xóa, 4 và 5 giữ lại.
Số không âm không bị xóa.
Không xóa 4 và 5.
Lời giải
Mã giữ lại các phần tử không âm. Cả -1 và -2 lần lượt được xóa, nên còn `[4, 5]`.
Mẫu dài ba có thể bắt đầu ở vị trí cuối hợp lệ
Muốn tìm mẫu `[1, 2, 3]` trong A, vị trí bắt đầu cuối cùng là `len(A) - 3`. Vì vậy vùng xét phải **gồm** vị trí đó: `range(len(A) - 2)` (với list đủ ba phần tử) hoặc vòng `while i <= len(A) - 3`. Nếu dùng dấu `< len(A) - 3`, trường hợp mẫu nằm sát cuối sẽ bị bỏ sót.
```python
A = [9, 1, 2, 3]
vi_tri = -1
for i in range(len(A) - 2):
if A[i:i + 3] == [1, 2, 3]:
vi_tri = i
break
print(vi_tri)
```
Mã in `1`. Thử `A = [1, 2, 3]` in 0; `A = [9, 8]` hoặc `[]` in -1. `-1` ở đây là **giá trị báo chưa tìm thấy** do chương trình đặt, không dùng làm chỉ số truy cập trong bài này.
Bài luyện
Với `A = [9, 1, 2, 3]`, mã tìm mẫu trong bài in vị trí nào?
Ở vị trí 0, ba phần tử là 9,1,2.
Mẫu 1,2,3 bắt đầu từ chỉ số 1.
Ở chỉ số 2 không còn đủ ba phần tử.
Mẫu được tìm thấy.
Lời giải
Các lát dài ba là `[9,1,2]` tại 0 và `[1,2,3]` tại 1. Mẫu khớp ở vị trí 1, nên in 1.
Bài luyện
Nếu A chỉ là `[1, 2, 3]`, mã trong bài có xét vị trí 0 không?
range(1) cho đúng giá trị 0.
Cách dùng dấu < sai mới bỏ sót trường hợp này.
Mẫu dài ba vừa đủ trong list dài ba.
Mẫu khớp nên in 0.
Lời giải
List dài 3, nên `range(3 - 2) = range(1)` có một lượt i = 0. Lát `A[0:3]` khớp mẫu và mã in 0.
Đang học