Bài tốn: một tập hợp hữu hạn cĩ n phần tử cĩ thể được biểu diễn tương đương với tập các số tự nhiên 1, 2, .., n.
Bài tốn đặt ra là: cho một tập hợp gồm n phần tử X = {X1, X2,.., Xn} hãy liệt kê tất cả các tập con của tập này.
Để biểu diễn tập con Y của X ta dùng xâu nhị phân Bn = {B1, B2,.., Bn}, sao cho nếu Bi
= 0 thì Xi∉ Y, ngược lại Bi = 1 thì Xi∈ Y.
Ví dụ như dãy 0011 của tập hợp gồm n thể hiện cho tập Y = {X3, X4} do phần tử B3 và B4 cĩ giá trị là 1.
Khi đĩ ta quy về bài tốn liệt kê tất cả xâu nhị phân cĩ kích thước n. Số các xâu nhị phân là 2n.
Một dãy nhị phân x độ dài n là biểu diễn một số nguyên p(x) nào đĩ trong đoạn [0, 2n- 1]. Do đĩ số các dãy nhị phân độ dài n = số các số nguyên ∈ [0, 2n-1] = 2n.
Mục tiêu là lập một chương trình liệt kê các dãy nhị phân n phần tử theo thứ tự từ điển, cĩ nghĩa là liệt kê dãy nhị phân biểu diễn các số nguyên theo thứ tự 0, 1,.., 2n-1.
Khi n =3, các độ dài 3 được liệt kê như sau:
p(x) 0 1 2 3 4 5 6 7
x 000 001 010 011 100 101 110 111
Khi đĩ dãy đầu tiên là: 000 và dãy cuối cùng là 111. Nhận thấy rằng nếu x là dãy đang cĩ và phải là dãy cuối cùng thì dãy tiếp theo cần liệt kê chính là x cộng thêm 1 đơn vị trong hệ nhị phân!
Ví dụ n = 6:
Dãy đang cĩ: 010000 Dãy đang cĩ: 010111
Cộng thêm 1: +1 Cộng thêm 1: +1
______ ______
Dãy mới: 010001 Dãy mới: 011000
Kỹ thuật sinh kế tiếp từ cấu hình hiện tại cĩ thể mơ tả như sau: xét từ cuối dãy lên từ hàng đơn vị tìm số 0 đầu tiên.
Nếu tìm thấy thì thay số 0 bằng số 1 và đặt tất cả phần tử phía sau vị trí đĩ bằng 0.
Nếu khơng tìm thấy thì tồn là dãy chứa 1, đây là cấu hình cuối cùng.
Chương trình minh họa 1: chương trình C/C++ liệt kê chuỗi nhị phân n bit.
int Stop; // biến tồn cục
void Next_BS(int B[MAX], int n) // Hàm phát sinh chuỗi kế tiếp
{
int i = n; // duyệt từ cuối
while (i>0 && B[i]) // lặp khi chưa tìm thấy B[i] ==0 {
B[i] = 0; // gán các bit sau là 0
i--; // giảm về trước
}
if (i==0 )
B[i] = 1; // gán 1 cho B[i] }
void Generate(int B[MAX], int n) // Hàm sinh chuỗi nhị phân
{
Stop = 0; while (! Stop) {
Result(B,n); // xuất chuỗi nhị phân hiện tại
Next_BS(B,n); // chuỗi nhị phân tiếp theo.
} }
void Result(int B[MAX], int n)
{
static int count=0;
printf(“\n Xau nhi phan thu %d”, ++count); for(int i=0; i < n;i++)
printf(“%3d”, B[i]); } int main() { int i, B[MAX], n; printf(“Nhap n: ”); scanf(“%d”,&n); for(i=0; i< n; i++)
B[i] =0; Generate(b, n); getch();
return 0; }