c++ - 从单个集合生成所有子集

标签 c++

我试图理解从一组中生成所有子集的代码。这是代码

#include <stdio.h>

/* Applies the mask to a set like {1, 2, ..., n} and prints it */
void printv(int mask[], int n) {
    int i;
    printf("{ ");
    for (i = 0; i < n; ++i)
        if (mask[i])
            printf("%d ", i + 1); /*i+1 is part of the subset*/
    printf("\\b }\\n");
}

/* Generates the next mask*/
int next(int mask[], int n) {
    int i;
    for (i = 0; (i < n) && mask[i]; ++i)
        mask[i] = 0;

    if (i < n) {
        mask[i] = 1;
        return 1;
    }
    return 0;
}

int main(int argc, char *argv[]) {
    int n = 3;

    int mask[16]; /* Guess what this is */
    int i;
    for (i = 0; i < n; ++i)
        mask[i] = 0;

    /* Print the first set */
    printv(mask, n);

    /* Print all the others */
    while (next(mask, n))
        printv(mask, n);

    return 0;
}

我不明白这行背后的逻辑 for (i = 0; (i < n) && mask[i]; ++i)在下一个函数中。这里如何生成下一个掩码?

代码和算法看这里: http://compprog.wordpress.com/2007/10/10/generating-subsets/

最佳答案

这只是 counting in binary 的一个实现.基本思想是将最不重要的(最后一个)零更改为 1,并将其之后的所有 1 更改为零。如果解释为二进制数,“下一个”掩码将比前一个掩码“多一个”。

因为数组是以个位在前排列的,所以从传统的数字记数法来看是倒着看的。

与其使用 bool 值数组,不如使用一个数字的二进制表示中的位和 ++ 运算符。

int next(int &mask, int n) { // using C++ reference
    if ( mask == ( 1u << n ) - 1 ) return 0;
    ++ mask;
    return 1;
}

void printv(int mask, int n) {
    int i;
    printf("{ ");
    for (i = 0; i < n; ++i)
        if (mask & ( 1 << i ) )
            printf("%d ", i + 1); /*i+1 is part of the subset*/
    printf("\\b }\\n");
}

自从您这样标记问题后,我使用了一点 C++,但发布的代码是纯 C。

关于c++ - 从单个集合生成所有子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10869866/

相关文章:

c++ - 我可以使用果酱来创建服务吗

c++ - C++ 中 main 之前发生了什么?

c++ - 如何从另一个类中访问一个类?

c++ - 堆二叉树打印方法

c++ - 有没有办法通过windbg查看堆栈帧上指针存储的地址?

c++ - 在 Linux Qt Creator C++ 中对 char * 使用 malloc 时接收 SIGSEGV 信号

c++ - tensorflow 将 softmax op 放在 cpu 而不是 gpu 上

c++ - 与任何类型的函数的接口(interface)

c++ - OS X 上 std::enable_shared_from_this<> 的编译错误

c++ - VC++ : How to get the time and date of a file?