#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
使用引用来避免不必要的拷贝,提高效率。