Mỗi phần tử dùng đúng một lần trong một nghiệm
```python
def genSentence(words, dictionary, k):
global count
if k == len(dictionary):
print(' '.join(words))
count += 1
else:
for word in dictionary:
if word not in words:
words.append(word)
genSentence(words, dictionary, k + 1)
words.pop()
```
dictionary chứa các từ khác nhau. words là tiền tố đã chọn; word not in words loại từ đã dùng trong nhánh hiện tại. append đưa từ mới vào, lời gọi nhỏ hoàn thành phần còn lại, pop khôi phục để thử từ khác.
Bắt đầu words=[] và k=0. Khi đủ len(dictionary) từ thì nối bằng dấu cách để xuất một cách sắp thứ tự. Quay về nhánh khác vẫn có thể dùng lại một từ, vì ràng buộc một lần chỉ áp dụng trong từng nghiệm.
Cùng điều kiện cho số nguyên phân biệt
Với các từ mây,qua,núi, có 3!=6 cách sắp thứ tự. Chương trình đang sinh hoán vị từ; không đánh giá cách sắp đó có đúng ngữ pháp hoặc ý nghĩa hay không.
```text
python3 g11-cs-thuc-hanh-quay-lui.py cau mây qua núi
python3 g11-cs-thuc-hanh-quay-lui.py hoan-vi 3
```
Lệnh đầu cần có sáu dòng hoán vị từ, bắt đầu “mây qua núi”, kết thúc “núi qua mây”. Lệnh sau dùng cùng cách kiểm phần tử chưa có với elements=[1,2,3], in đủ sáu hoán vị số. Không được nhầm với sinh dãy cho phép lặp: [1,1,2] không là hoán vị của [1,2,3].
Tệp tải có hàm genPermutations tương ứng mã của SGV. Dãy số đầu vào được tạo từ 1 đến n; trước mỗi lượt đặt count=0. Bản từ yêu cầu các từ khác nhau để phép kiểm theo giá trị không chặn nhầm một lần xuất hiện cần dùng.
Bài luyện
Điều kiện word not in words có tác dụng gì?
Các nhánh thử tạo nhiều thứ tự khác nhau.
Mỗi từ chỉ xuất hiện một lần trong một hoán vị.
Sau khi pop, nhánh khác vẫn có thể chọn từ ấy.
dictionary không bị xóa phần tử.
Lời giải
words chứa các từ đã chọn của nhánh đang xét. Kiểm thành viên giúp tránh dùng lại trong nhánh ấy; các nhánh khác độc lập và vẫn được chọn đủ các từ.
Bài luyện
Tập [1,2,3] có bao nhiêu hoán vị?
Không có ba lựa chọn độc lập ở mỗi vị trí.
27 là số dãy dài 3 khi mỗi vị trí được dùng lại một trong ba số.
Có 3×2×1=6 cách chọn không lặp.
3 chỉ là số phần tử.
Lời giải
Chọn vị trí đầu có 3 cách, vị trí thứ hai còn 2, vị trí cuối còn 1. Tổng số hoán vị là 6.
Bài luyện
Vì sao cần pop sau genSentence ở một nhánh?
Chỉ danh sách words được thay đổi.
Các nghiệm đã in vẫn là kết quả hợp lệ.
pop chỉ xóa phần tử cuối.
Khôi phục tiền tố đúng như trước append.
Lời giải
Một từ được append để đi tiếp ở nhánh hiện tại. Khi trở về, xóa đúng từ đó giúp trạng thái của mức trước còn nguyên để thử lựa chọn kế tiếp.
Đang học