Ghép thêm một chữ số ở bên phải
Xét xâu không rỗng s chỉ gồm các kí tự 0 và 1. Khi ghép thêm một chữ số ở bên phải biểu diễn nhị phân, mỗi chữ số cũ tăng một bậc nên giá trị phần cũ được nhân 2; sau đó cộng chữ số mới.
Gọi D(n) là giá trị của n kí tự đầu. Với $n=1$, $D(1)=\operatorname{int}(s[0])$. Với $n>1$:
$$D(n)=2D(n-1)+\operatorname{int}(s[n-1]).$$
Hàm int đổi kí tự `'0'` hoặc `'1'` thành số để tính toán.
Dừng khi phần đầu chỉ còn một kí tự
```python
def dec(s, n):
if n == 1:
return int(s[0])
return 2 * dec(s, n - 1) + int(s[n - 1])
```
Gọi `dec(s, len(s))`. Điều kiện của hàm là s không rỗng, chỉ gồm 0/1 và 1≤n≤len(s). Xâu `'0'` là đầu vào hợp lệ và cho 0; xâu rỗng không thuộc điều kiện của hàm này, cần được chặn trước khi gọi.
Theo dõi giá trị khi các lời gọi trả về
Với s=`'10101'`, các lời gọi đi từ n=5 về cơ sở n=1. Khi trả về, phần đầu dài dần như sau:
| Phần đầu | Cách tính | Giá trị |
|---|---|---|
| 1 | Cơ sở | 1 |
| 10 | 2×1+0 | 2 |
| 101 | 2×2+1 | 5 |
| 1010 | 2×5+0 | 10 |
| 10101 | 2×10+1 | 21 |
Mỗi bước ghép thêm đúng chữ số cuối của phần đầu đang xét, không cộng trực tiếp tất cả các chữ số.
Khi đầu vào là danh sách các số 0 và 1
Với A là danh sách số nguyên 0/1, A[n−1] đã là số nên không cần int. Bản dưới chọn cơ sở n=0 để giá trị phần đầu rỗng bằng 0:
```python
def dec_list(A, n):
if n == 0:
return 0
return 2 * dec_list(A, n - 1) + A[n - 1]
```
Gọi với n=len(A); điều kiện là 0≤n≤len(A). Ví dụ [0,1,0,1] cho 5; chữ số 0 đầu không làm đổi giá trị. Quy ước phần đầu rỗng bằng 0 của hàm này không làm xâu rỗng trở thành một biểu diễn nhị phân hợp lệ cho hàm dec ở trên.
Bài luyện
Theo hàm dec trong bài, dec('10101',5) trả về bao nhiêu?
10 còn thiếu bước ghép chữ số cuối.
Đó là đọc các chữ số như một số thập phân.
Phần đầu 1010 có giá trị 10, rồi ghép 1 được 2×10+1.
5 là giá trị của phần đầu 101.
Lời giải
Từ cơ sở 1, các giá trị lần lượt là 1, 2, 5, 10, 21 theo bảng. Vì vậy kết quả cuối là 21.
Bài luyện
Vì sao bước ghép chữ số cuối cần nhân giá trị phần đầu với 2?
Hệ thập phân sẽ dùng hệ số 10, khác đầu vào đang xét.
Số chữ số 1 không quyết định hệ số này.
Độ dài xâu không phải hệ số của bước ghép.
Một bậc của hệ nhị phân ứng với hệ số 2.
Lời giải
Ghép thêm một chữ số ở bên phải làm các chữ số cũ dịch sang bậc cao hơn. Trong hệ nhị phân, mỗi bậc cao hơn có trọng số gấp 2, nên giá trị phần đầu được nhân 2 rồi cộng chữ số mới.
Bài luyện
Hàm dec chọn cơ sở n==1. Nhận xét nào đúng về hai đầu vào '0' và xâu rỗng?
Xâu một kí tự dùng cơ sở; xâu rỗng không thỏa điều kiện của hàm.
Hàm đang dùng chưa có cơ sở n==0.
Kí tự 0 thuộc tập chữ số nhị phân.
Xâu rỗng không có phần tử để đọc.
Lời giải
Với s='0', len(s)=1 nên hàm trả int(s[0])=0. Với s rỗng, n=0 không đạt cơ sở n==1 và cũng không có s[0], nên phải kiểm đầu vào trước lời gọi.
Bài luyện
Với bản dec_list trong bài, dec_list([0,1,0,1],4) trả về bao nhiêu?
4 chỉ là số phần tử.
Các phần đầu cho giá trị 0, 1, 2, 5.
2 mới là giá trị của phần đầu [0,1,0].
10 là nhân thêm 2 nhưng chưa đúng bước cuối.
Lời giải
Từ cơ sở phần đầu rỗng bằng 0: ghép lần lượt 0,1,0,1 cho 0,1,2,5. Vì vậy giá trị cần tìm là 5.
Đang học