#include <iostream> // 包含输入输出流头文件
#include <vector> // 包含vector容器头文件
#include <cmath> // 包含数学函数头文件,用于pow函数
using namespace std; // 使用std命名空间,避免每次都写std::
// 定义生成幂集的函数
vector<vector<int>> generatePowerSet(vector<int>& set) {
int n = set.size(); // 获取集合的大小
int powerSetSize = pow(2, n); // 计算幂集的大小,2的n次方
vector<vector<int>> powerSet; // 创建一个二维vector来存储幂集
// 遍历从0到2^n-1的所有数
for (int i = 0; i < powerSetSize; i++) {
vector<int> subset; // 创建一个vector来存储当前子集
// 检查i的每一位
for (int j = 0; j < n; j++) {
// 如果i的第j位是1,则将set的第j个元素加入子集
if (i & (1 << j)) {
subset.push_back(set[j]);
}
}
powerSet.push_back(subset); // 将生成的子集加入幂集
}
return powerSet; // 返回生成的幂集
}
int main() {
vector<int> set = {1, 2, 3}; // 创建一个示例集合
// 调用generatePowerSet函数生成幂集
vector<vector<int>> powerSet = generatePowerSet(set);
cout << "Power set:" << endl; // 输出提示信息
// 遍历幂集中的每个子集
for (const auto& subset : powerSet) {
cout << "{ "; // 输出子集的开始符号
// 遍历子集中的每个元素
for (int elem : subset) {
cout << elem << " "; // 输出元素和一个空格
}
cout << "}" << endl; // 输出子集的结束符号和换行
}
return 0; // 程序正常结束
}
关键点解释:
pow(2, n)
计算2的n次方,这是因为对于n个元素的集合,每个元素有"选"和"不选"两种可能,所以总共有2^n种组合。i & (1 << j)
是一个位操作,用来检查数字i的第j位是否为1:1 << j
将1左移j位,例如1 << 2
结果是二进制的100(十进制的4)i & (1 << j)
如果结果非零,说明i的第j位是1
- 外层循环
for (int i = 0; i < powerSetSize; i++)
遍历了所有可能的选择组合,每个i代表一种选择方式。 - 内层循环
for (int j = 0; j < n; j++)
检查每个i的每一位,决定是否选择对应的元素。 const auto& subset
使用引用来避免不必要的拷贝,提高效率。