【问题标题】:set_union() is not working for a set of stringsset_union() 不适用于一组字符串
【发布时间】:2020-01-25 09:27:15
【问题描述】:

我试图找出两个包含字符串的集合的并集,使用set_union(...) 函数。但是,它在stl_algo.h ar line no 4948 内抛出错误-

错误: passing 'const std::__cxx11::basic_string<char>' as 'this' argument discards qualifiers [-fpermissive]

我的代码:

#include<bits/stdc++.h>

using namespace std;

int main()
{
    int t,k, tmp, i=1,j,l,m,n,x1,x2;
    cin>>n;
    string st,stt;
    set <string> set1,set2,set3;
    set1.insert("sdsd");
    set1.insert("sdswewd");
    set1.insert("ssd");

    set2.insert("sdsd");
    set2.insert("sdfewew");
    set2.insert("ssd");
    set_union(set1.begin(),set1.end(),set2.begin(),set2.end(),set3.begin());

    return 0;
}

【问题讨论】:

标签: c++ set-union


【解决方案1】:

尝试使用std::inserter

set_union( set1.begin(), set1.end(), set2.begin(), set2.end(),std::inserter( set3, set3.begin() ));

更新:

a1.begin() 根本不是输出迭代器。插入器(a1,a1.begin()) 返回一个输出迭代器,它将调用集合的插入函数 对于每个元素... Why do we need an inserter function call when doing a set_union for a set?

此外,由于我们正在处理 std::set 一个保证唯一性的容器,我们不需要采用 set_union,因为简单的集合插入也将确保它不会创建相同元素的副本。

//insert all element of set 1 to set 3
set3.insert(set1.begin(),set1.end());
//insert all elements of set 2 (that is not in set 1) to set 3
set3.insert(set2.begin(),set2.end());

【讨论】:

  • 这个答案是正确的,但你应该解释一下原始代码中的问题是什么,以及为什么它会修复它。
【解决方案2】:

正如另一个答案中提到的,std::inserter 可以完成这项工作。或者,您可以将set_union 的输出存储在vector 中,如有必要,使用输出vector 中的值构造另一个set

但是,应该注意的是,这种方法要求您在运行时(由用户设置)或编译时知道向量的大小。在后一种情况下,您可以使用std::array。如果输出未知(即计算),则输出向量可能足够大以存储结果,您的程序将崩溃(内存泄漏)。

#include<iostream>
#include<set>
#include<string>
#include<algorithm>
#include<vector>

int main()
{
    std::set<std::string> set1,set2;
    set1.insert("sdsd");
    set1.insert("sdswewd");
    set1.insert("ssd");

    set2.insert("sdsd");
    set2.insert("sdfewew");
    set2.insert("ssd");

    std::vector<std::string> output(4);
    std::set_union(set1.begin(),set1.end(),set2.begin(),set2.end(),output.begin());

    std::set<std::string> set3(output.begin(),output.end());
}

在线示例:https://rextester.com/MUPHB45816

还有一个使用向量的代码示例here

【讨论】:

  • 我强烈反对使用 begin() 迭代器作为输出的预调整大小的输出向量。最好只使用一个 back_inserter。否则其他输出会发生坏事
  • @phön:是的。我同意inserterback_inserter 是更好的选择。我刚刚发布了答案作为替代选项。此外,如果需要,您可以调整std::vector 的大小以适应std::set 的内容。
  • 如何调整 std::vector 的大小以适应集合?哪一套。你事先不知道尺寸。假设您的向量已经足够大,std::set_union 将很高兴地插入迭代器。如果您输入较少的值,您将拥有一个带有默认构造字符串的向量。如果您输入更多,则您有未定义的行为(超出范围)。这个解决方案是自找麻烦,这与向量本身的使用无关。只是你对向量的使用不好。
  • @phön:使用向量的代码示例中显示了将向量大小调整为设置边界的示例。我再次同意,当输出大小未知时,这种方法不如inserter 解决方案优雅。但是,这是一种替代方法,并且有其用途。例如,如果您在运行时知道元素的数量,那么使用vector 比使用set 快得多。如果您在编译时知道元素的数量,那么array 会更好。你不必被卷起来。这就是编程。解决问题的方法不止一种。
  • @phön:是的,确实如此。如果您将输入更改为您建议的内容,那么输出vector 将不够大并且会崩溃。毫无疑问或争论。这就是为什么我说如果您在运行时(即由用户设置)或编译时知道大小,那么使用vectorarray 将更好地匹配inserter 算法。在任何其他情况下,您是正确的,它会导致问题。但是我没有在回答中说清楚,我并没有真正想到有人可能会蒙着眼睛复制这段代码。谢谢,我会修改的。
猜你喜欢
  • 2019-12-21
  • 2014-07-13
  • 2020-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多