对字符串使用 set_union
Using set_union for strings
我有两个向量,我需要它们在第三个向量中的并集(不指定第三个向量的大小(
std::vector<std::string> a = {"a","b"};
std::vector<std::string> b = {"d","c"};
std::vector<std::string> c;
std::set_union(a.begin(),a.end(),b.begin(),b.end(),c.begin());
std::cout<<c[1];
这将编译,但给出一个空输出。
算法std::set_union
需要有序序列。 在您的字符串示例中,第一个向量按升序排序,第二个向量按降序排序。
此外,向量c
为空,因此您不能在算法调用中使用表达式c.begin()
。您需要使用std::back_insert_iterator
.
对于字符串示例,算法的调用可以如下所示,如演示程序所示。
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
int main()
{
std::vector<std::string> a = { "a", "b" };
std::vector<std::string> b = { "d", "c" };
std::vector<std::string> c;
std::set_union( std::begin( a ), std::end( a ),
std::rbegin( b ), std::rend( b ),
std::back_inserter( c ) );
for ( const auto &s : c ) std::cout << s << ' ';
std::cout << 'n';
return 0;
}
它的输出是
a b c d
否则,您需要对向量进行排序。
如果您可能无法对原始向量进行排序,则可以使用以下方法
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
int main()
{
std::vector<std::string> a = { "a", "b" };
std::vector<std::string> b = { "d", "c", "a" };
std::vector<std::string> c( a );
c.insert( std::end( c ), std::begin( b ), std::end( b ) );
std::sort( std::begin( c ), std::end( c ) );
c.erase( std::unique( std::begin( c ), std::end( c ) ), std::end( c ) );
for ( const auto &s : c ) std::cout << s << ' ';
std::cout << 'n';
return 0;
}
程序输出为
a b c d
你的代码有两个问题:
- 您没有阅读
std::set_union
的要求 - 输入范围必须根据给定的比较函数进行排序(在您的情况下operator<
( - 这不适用于b
. - 该算法不能通过
c.begin()
调整c
的大小;它保持为空,并且您写出界外。使用std::back_insert_iterator
.
使用std::set_union()
算法的替代方法是使用std::set
或std::unordered_set
容器来存储两个向量的所有元素,然后从该容器初始化生成的向量。
这种方法的缺点是,额外的容器需要跨两个向量的唯一元素数量的线性空间。
使用哪个容器将取决于您是否需要对生成的向量进行排序。如果您不需要对生成的向量进行排序,则可以使用std::unordered_set
:
std::vector<std::string> make_unsorted_union(const std::vector<std::string>& a,
const std::vector<std::string>& b)
{
std::unordered_set<std::string> st;
for (auto& str: a)
st.insert(str);
for (auto& str: b)
st.insert(str);
return std::vector<std::string>(st.begin(), st.end());
}
将元素插入std::unordered_set
平均可以在恒定时间内完成。
如果需要对生成的向量进行排序,则可以改用std::set
:
std::vector<std::string> make_sorted_union(const std::vector<std::string>& a,
const std::vector<std::string>& b)
{
std::set<std::string> st;
for (auto& str: a)
st.insert(str);
for (auto& str: b)
st.insert(str);
return std::vector<std::string>(st.begin(), st.end());
}
这些函数可以按如下方式使用:
int main() {
std::vector<std::string> a = {"a", "z", "z", "b", "z"};
std::vector<std::string> b = {"d", "v", "c", "x", "e"};
std::vector<std::string> c = make_unsorted_union(a, b);
for (auto& str: c)
std::cout << str << ' ';
std::cout << 'n';
c = make_sorted_union(a, b);
for (auto& str: c)
std::cout << str << ' ';
std::cout << 'n';
}
我这个程序的输出是:
e c x b v d z a
a b c d e v x z
相关文章:
- 为什么我无法更改"set<set>"循环中的值<int>
- 对于set上的循环-获取next元素迭代器
- C++Union/Struct位域的实现和可移植性
- 在声明中合并两个常量"std::set"(不是在运行时)
- 有没有办法对std::unordered_set、std::unrdered_map、std::set、std::map
- 将 std::set 与基于键的比较器一起使用
- 如何使用set实现无序数据结构?
- 使用运算符调用 void 函数时出错<set>
- 修改"std::set"中用户定义类型的值
- 如何通过多类"Union variable" (sfml) 使用轮询事件
- 错误:"Left of getValue must have class/struct/union"
- 生成提升::hana::set 的常量表达式问题
- 如何在构造函数参数中初始化"std::set"?
- 如何使用 lower_bound/upper_bound 从 std::set 获取索引号?
- 如何在 C++ 中转发声明 std::set?
- C++Union,两个活跃成员,仅简历资格不同
- 重构使用动态强制转换的 std::set 的比较运算符
- 如何以"union-like"方式更改C++向量的数据类型
- set::find 查找不存在的元素
- 我对set.union(C++)有问题