Lỗi chương trình liệt kê tập con

Trong bài toán liệt kê tất cả tập con của tập n phần tử {1, 2, 3, … n}, chương trình của em gồm những phần như sau.

  1. Xây dựng hàm void tapCon(int n, int k) trong đó n là số phần tử tập mẹ, k là số phần tử tập con.
  2. main(), nhập n từ bàn phím. Khai báo k và dùng vòng lặp for(k = 0; k <= n; k++) để in ra tập con có 0, 1, 2, … n phần tử.

(Em để code bên dưới nếu mọi người cần ạ!)

Nhưng khi chạy thì kết quả chỉ hiện với trường hợp giá trị khởi tạo của k trong vòng for, chứ không phải từ 0 đến n.

Mọi người có thể giải thích cho em được không ạ?

void TapCon(int n, int k)
{
    int *a = NULL, i = 0;
    // Tạo mảng a chứa các số từ 1 đến k
    a = malloc(k * sizeof(int));
    if (a == NULL) exit(0);
    for (i = 0; i < k; i ++)
        a[i] = i + 1;

    // Thực hiện việc tìm trường hợp thỏa mãn bằng phương pháp sinh.
    while(i >= 0)
    {
        for (i = 0; i < k; i ++)
            printf("%d ", a[i]);
        printf("\n");

        i = k - 1;
        while (a[i] >= n - (k - 1) + i && i >= 0)
            i --;
        if (i < 0) exit(0);

        a[i] ++;
        for (int j = 1; j < k - i; j ++)
            a[i + j] = a[i] + j;
    }
    free(a);
}

int main(int argc, char* argv[])
{
    int n = 0, k = 0;
    scanf("%d", &n);

    for (k = 0; k <= n; k ++)
        TapCon(n, k);
    return 0;
}

Đổi exit(0) thành return. Thêm phần ép kiểu chỗ malloc là chạy ngon :kissing_smiling_eyes:


Cách khác để liệt kê với tập hợp bất kì, gồm 3 bước.

Bước 1:
Sắp xếp các phần tử trong tập hợp theo một total order bất kì.
Ví dụ: { a, c, d, b } sắp xếp theo total order là thứ tự alphabet thì có tập là { a, b, c, d }

Bước 2:
Tạo các số nhị phân có chiều dài bằng số phần tử tập hợp, liệt kê tất cả số nhị phân có cùng chiều dài.
Ví dụ: tập trên có số phần tử bằng 4, tập nhị phân là { 0000, 0001, 0010, …, 1110, 1111 }

Bước 3:
Thực hiện mapping từng số nhị phân với 1 tập con, nếu chữ số bằng 1 thì thực hiện map, nếu là 0 thì không map. Hàng đơn vị là ‘a’, hàng 2 là ‘b’, hàng 4 là ‘c’,…
Ví dụ: 0001 -> { a }, 0101 -> { a, c }, 1111 -> { a, b, c, d }, 0000 -> { }

Số lượng số nhị phân có chiều dài n là 2n, tương ứng với số lượng tập con của 1 tập n phần tử là 2n. Chỉ cần liệt kê các số nhị phân là có đủ số tập con. Cách liệt kê thì đơn giản, cho 1 vòng for từ 0 đến 2n-1 là xong rồi. :kissing_smiling_eyes:

#include <iostream>
#include <vector>
#include <bitset>
#include <cmath>

int main() {
    int n = 4;
    std::vector<char> chrs { 'a', 'b', 'c', 'd' };
    
    int max = int(std::pow(2, n) + 0.1);
    for (int i = 0; i < max; i++) {
        std::bitset<16> bits(i);
        std::cout << "{ ";
        for (int j = 0; j < n; j++)
            if (bits[j]) std::cout << chrs[j] << " ";
        std::cout << "}\n";
    }
}
4 Likes

:sweat_smile: em cảm ơn anh ạ! Nhờ câu trên mà em đã biết được thêm kiến thức về return, exitbreak.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?