:编写程序生成一个集合的所有子集(c++语言),采用递归或非递归的方式皆可
时间: 2024-09-07 14:03:44 浏览: 128
在C++中,生成一个集合的所有子集可以通过两种方式实现:递归和非递归。这里我会分别给你演示这两种方法。
**1. 递归方法:**
递归是一种自然的选择,因为集合的子集问题很容易用递归来定义:每个元素要么被包含在子集中,要么不被包含。我们可以从空子集开始,然后为每个元素添加到当前子集中,生成新的子集。
```cpp
#include <iostream>
#include <vector>
#include <algorithm>
void generateSubsets(std::vector<int>& nums, std::vector<int>& subset, int index = 0) {
// 如果已经到了序列的末尾,输出当前子集
if (index == nums.size()) {
for (int num : subset) {
std::cout << num << " ";
}
std::cout << "\n";
return;
}
// 不包含当前元素的情况
generateSubsets(nums, subset, index + 1);
// 包含当前元素的情况
subset.push_back(nums[index]);
generateSubsets(nums, subset, index + 1);
// 注意:递归调用后要移除最后一个元素,以回溯到上一步
subset.pop_back();
}
// 主函数调用
void generateAllSubsets(const std::vector<int>& nums) {
std::vector<int> subset;
generateSubsets(nums, subset);
}
int main() {
std::vector<int> numbers = {1, 2, 3};
std::cout << "Generating all subsets of the set: ";
generateAllSubsets(numbers);
return 0;
}
```
**2. 非递归方法(动态规划):**
非递归的方法通常使用迭代,通过维护两个指针 `begin` 和 `end` 来追踪子集范围。每次移动 `end` 指针就可以生成一个新的子集。
```cpp
#include <iostream>
#include <vector>
void generateSubsetsNonRecursive(const std::vector<int>& nums) {
std::vector<std::vector<int>> subsets;
subsets.reserve(1 << nums.size()); // 计算所有可能的子集数量
// 初始化第一个子集为空
subsets.push_back({});
// 使用两层循环遍历所有可能的子集
for (size_t i = 0; i < nums.size(); ++i) {
size_t end = subsets.size();
// 将当前元素添加到现有的每个子集中
for (std::vector<int>& subset : subsets) {
subsets.push_back(subset);
subsets.back().push_back(nums[i]);
}
// 删除重复的子集(由于包含相同元素的不同顺序)
subsets.erase(subsets.begin(), subsets.end() - end);
}
// 输出所有子集
for (const std::vector<int>& subset : subsets) {
for (int num : subset) {
std::cout << num << " ";
}
std::cout << "\n";
}
}
int main() {
std::vector<int> numbers = {1, 2, 3};
std::cout << "Generating all non-recursive subsets of the set: ";
generateSubsetsNonRecursive(numbers);
return 0;
}
```
阅读全文