C# 如何查找集合的所有分区(C+;+;)
我用C#编写了以下代码,用于计算集合的分区 摘自 这里发生了什么?如果我删除yield关键字,代码将不起作用。这段代码也不是递归的,所以我不知道这里发生了什么 编辑: >我把它移植到C++。谢谢大家:C# 如何查找集合的所有分区(C+;+;),c#,c++,C#,C++,我用C#编写了以下代码,用于计算集合的分区 摘自 这里发生了什么?如果我删除yield关键字,代码将不起作用。这段代码也不是递归的,所以我不知道这里发生了什么 编辑: >我把它移植到C++。谢谢大家: std::vector<std::vector<std::vector<int>>> getPartitions(const std::vector<int>& elements){ std::vector<std::vecto
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;
}
std::vector getPartitions(const std::vector&elements){
std::向量fList;
向量表;
向量索引(elements.size(),0);//分配?
lists.emplace_back(std::vector());
列表[0]。插入(列表[0]。结束(),元素。开始(),元素。结束());
int计数器=-1;
对于(;;){
计数器+=1;
返回(列表);
int i,索引;
布尔obreak=假;
对于(i=index.size()-1;;--i){
if(i0)
打破
lists.erase(lists.begin()+索引);
}
如果(障碍物)破裂;
++指数;
如果(索引>=lists.size())
lists.emplace_back(std::vector());
对于(;i长话短说,为返回的列表引入一个变量'results',并在函数开头初始化它。然后将收益率返回x转换为结果。添加(x),并将收益率中断转换为返回结果
可能还有其他方法可以在不占用内存的情况下存储结果,但确实很难。就我个人而言,我喜欢屈服返回的令人费解的特性。简洁地解释起来并不容易,但这有点像是在放下堆栈继续执行调用函数时暂停执行方法。当调用函数请求迭代中的下一项时,您将在收益返回后的下一条语句处继续。我确信编译器人员会对这样的解释感到不满,但这对我来说是有效的。这回答了您的问题吗?这不是我所说的好C代码(我对for循环一点都不满意)咬紧牙关允许一次计算一个IdEnable中的单个项,你应该能够从微软上学习你需要的,我想现在是时候咬紧牙关,理解这个过程中的收益率了。从来没有想过把一个函数移植到C++会导致一整天的工作,这一部分可能会让人困惑。内容并不代表一个函数,它们代表一个类。函数的所有内部状态最终都被隐藏在一个隐藏的类中,该类跟踪函数在执行中的位置和所有变量。屈服返回的强大功能使得在没有它的语言中进行模拟需要做大量的工作。@raaj检查表达式,它是C语言的一部分++20规格。
for (;;) {
yield return lists;
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;
}