如何查找集合的所有分区 (C++)

How to find all partitions of a set (C++)

本文关键字:分区 C++ 集合 查找 何查找      更新时间:2023-10-16

我在 C# 中有以下代码来计算集合的分区

取自(如何查找集合的所有分区(

public static IEnumerable<List<List<T>>> GetAllPartitions<T>(T[] elements) {
var lists = new List<List<T>>();
var indexes = new int[elements.Length];
lists.Add(new List<T>());
lists[0].AddRange(elements);
for (;;) {
yield return lists;
int i,index;
for (i=indexes.Length-1;; --i) {
if (i<=0)
yield break;
index = indexes[i];
lists[index].RemoveAt(lists[index].Count-1);
if (lists[index].Count>0)
break;
lists.RemoveAt(index);
}
++index;
if (index >= lists.Count)
lists.Add(new List<T>());
for (;i<indexes.Length;++i) {
indexes[i]=index;
lists[index].Add(elements[i]);
index=0;
}
}

我的任务是将此代码移植到C++。不幸的是,yield 关键字让我失望了。

在本节中,此处:

for (;;) {
yield return lists; 

这是怎么回事?如果我删除 yield 关键字,代码不起作用。这段代码也不是递归的,所以我不知道这里发生了什么

编辑:

好的,我把它移植到C++。谢谢大家:

std::vector<std::vector<std::vector<int>>> getPartitions(const std::vector<int>& elements){
std::vector<std::vector<std::vector<int>>> fList;
std::vector<std::vector<int>> lists;
std::vector<int> indexes(elements.size(), 0); // Allocate?
lists.emplace_back(std::vector<int>());
lists[0].insert(lists[0].end(), elements.begin(), elements.end());
int counter = -1;
for(;;){
counter += 1;
fList.emplace_back(lists);
int i,index;
bool obreak = false;
for (i=indexes.size()-1;; --i) {
if (i<=0){
obreak = true;
break;
}
index = indexes[i];
lists[index].erase(lists[index].begin() + lists[index].size()-1);
if (lists[index].size()>0)
break;
lists.erase(lists.begin() + index);
}
if(obreak) break;
++index;
if (index >= lists.size())
lists.emplace_back(std::vector<int>());
for (;i<indexes.size();++i) {
indexes[i]=index;
lists[index].emplace_back(elements[i]);
index=0;
}
}

return fList;
}
int main()
{
std::vector<int> elements = {0,1,2,3,4,5};
auto fLists = getPartitions(elements);
for(auto& lists : fLists){
for(auto& l : lists){
std::cout << "(";
for(auto& e : l){
std::cout << e << " ";
}
std::cout << ") ";
}
std::cout << std::endl;
std::cout << "--" << std::endl;
}
return 0;
}

长话短说,为返回的列表列表引入一个变量"results",并在函数开始时对其进行初始化。然后将收益率回报 x 转换为结果。Add(x(,并将良率分解转换为返回结果。

可能还有其他方法可以在不占用内存来存储结果的情况下做到这一点,但可以肯定的是,它们很困难。就我个人而言,我喜欢收益率回报的令人费解的品质。简洁地解释不太容易,但这有点像暂停执行方法,同时在堆栈上下拉以继续执行调用函数。当调用函数请求迭代中的下一项时,您将在收益返回后的下一条语句处继续。我相信编译器的人会对这样的解释呻吟,但它对我有用。