gpt4 book ai didi

c++ - 使用 set_union 和 set_intersection 时出错

转载 作者:太空宇宙 更新时间:2023-11-03 10:34:55 25 4
gpt4 key购买 nike

我有两个集合,我正在尝试做一个并集(我在做一个交集时得到同样的错误)。这是错误:

error C3892: 'std::_Tree_const_iterator<_Mytree>::operator *' : you cannot assign to a variable that is const

代码片段(如果我用 --> 注释掉该行,那么代码会编译并且我围绕 union 的方式工作正常):

    set<Line *>::iterator it;
set<Line *> * newSet = new set<Line *>();
leftLines = pLeft->getSet();
rightLines = pRight->getSet();
-->it = set_union(leftLines->begin(),leftLines->end(),rightLines->begin(), rightLines->end(), newSet->begin());
for(it = leftLines->begin(); it != leftLines->end(); it++)
{
newSet->insert(*it);
}
for(it = rightLines->begin(); it != rightLines->end(); it++)
{
newSet->insert(*it);
}
it = newSet->begin();
while(it != newSet->end())
{
result->insert(*it);
it++;
}

我确定这很愚蠢,但我有点迷路了。我认为代码片段应该足够了,但我可以提供任何其他需要的东西。谢谢。

最佳答案

这是 C++,而不是 Java [编辑:或 .NET]。您几乎肯定想要替换(例如):

set<Line *> * newSet = new set<Line *>();

只有:

set<Line *> newSet;

...或者,更好的是,可能只是:

set<Line> newSet;

尽管根据您发布的代码无法确定,但您的 leftright 很有可能不应该处理指针要么——如果他们打算做任何类似的事情,引用可能更有意义(尽管,正如我所说,仅根据您发布的内容,不可能肯定地说)。

完成后,您会遇到一个小问题:set(或multisetmap)上的“普通”迭代器> 或 multimap) 实际上是一个 const_iterator。一旦将某些东西插入到关联容器中,就不允许更改它,因为这可能会破坏集合的不变性(正在排序)。如果要更改现有项目,则需要从容器中删除 if,进行更改,然后将更改的对象插入回容器中。在您的情况下,您只是插入新项目,因此您需要一个 insert_iterator

由于您不打算修改 leftright,因此您也可以将它们视为 const:

std::set_union(left.cbegin(), left.cend(), 
right.cbegin(), right.cend(),
std::inserter(newSet, newSet.end()));

如果您决定自己模拟 set_union,您可以这样做:

std::set<Line> newSet(left.cbegin(), left.cend());  
std::copy(right.cbegin(), right.cend(), std::inserter(newSet, newSet.end()));

编辑:

您通常不想传递指向容器的指针,而是传递迭代器到容器中。例如,要打印出内容,您显然现在有类似的东西:

void print_data(std::vector<Line *> const *data) { 
for (int i=0; i<data->size(); i++)
std::cout << *(*data)[i] << "\n";
}

它可能有更多的格式等等,但目前我们将忽略这些细节并假设它就是这么简单。要直接从您选择的容器写入数据,您通常需要一个接受任意类型迭代器的模板:

template <class inIt>
void print_data(inIt begin, inIt end) {
while (begin != end)
std::cout << *begin++ << '\n';
}

但是,我们可以更进一步,将输出也指定为迭代器:

template <class inIt, class outIt>
void print_data(inIt begin, inIt end, outIt dest) {
while (begin != end) {
*dest++ = *begin++;
*dest++ = '\n';
}
}

您可以再走一步,允许用户指定要在项目之间使用的分隔符,而不是总是使用“\n”,但在这一点上,您只是在复制已经在项目中的内容标准库 -- std::copystd::ostream_iterator 的组合,这就是您可能希望在现实中处理此问题的方式:

std::copy(newSet.begin(), newSet.end(), 
std::ostream_iterator<Line>(std::cout, "\n"));

但是请注意,就标准库而言,ostream_iterator 只是另一个迭代器。如果你只是想打印出 leftright 的并集,你甚至可以跳过创建一个集合来保存那个并集,直接打印出来:

std::set_union(left.cbegin(), left.cend(),
right.cbegin(), right.cend(),
std::ostream_iterator<Line>(std::cout, "\n"));

ostream_iterator 写入文件而不是将内容放入普通集合这一事实与标准库完全无关。它有几个迭代器类,可以将输出写入任何模拟正确类的迭代器。

现在,我可能是仓促行事,可以这么说——在将数据写入控制台之前,可能需要对数据进行其他处理。我的意思并不是说您必须将 union 直接写入标准输出,而只是说在打印出来之前您不一定必须将它写入其他集合。

关于c++ - 使用 set_union 和 set_intersection 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5665058/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com