C++ 如何使用“合并”来合并两个贴图/多重贴图(C+;+;11 STL)

C++ 如何使用“合并”来合并两个贴图/多重贴图(C+;+;11 STL),c++,stl,merge,multimap,C++,Stl,Merge,Multimap,我的项目涉及分而治之的策略,以对现有算法进行并行化。 该算法返回一个std::multimap。上面是一个前螺旋(单螺纹)版本的草图 typedef std::multimap映射; 结构盒 { 标准::对左上下; } 映射我的算法(长方体,长方体) { 地图终稿; 如果(不是小的(盒子)) { 框b1、b2; split_-box(a_-box,&b1,&b2);//此函数将长方体分成两半 Map m1=我的算法(b1); Map m2=我的算法(b2); //此行将不编译。不接受final_

我的项目涉及分而治之的策略,以对现有算法进行并行化。 该算法返回一个
std::multimap
。上面是一个前螺旋(单螺纹)版本的草图

typedef std::multimap映射;
结构盒
{
标准::对左上下;
}
映射我的算法(长方体,长方体)
{
地图终稿;
如果(不是小的(盒子))
{
框b1、b2;
split_-box(a_-box,&b1,&b2);//此函数将长方体分成两半
Map m1=我的算法(b1);
Map m2=我的算法(b2);
//此行将不编译。不接受final_m.begin()。
合并(m1.begin(),m1.end(),m2.begin(),m2.end(),final_m.begin());
}
返回最终值;
}
我知道我可以使用insert或merge来进行合并(如上所述)。但是insert在O(N.Log(N))中,merge在O((N))中。由于算法中涉及的合并操作的数量,时间复杂度很重要

谢谢你的帮助, 奥利维尔

编辑:

感谢jogojapan(参见下面的答案),这是一个正确代码的工作演示:

#include <iostream>
#include <map>
#include <iterator>
#include <algorithm>

typedef std::pair<int, int> Cell ;
typedef std::multimap<int, Cell> Border_map ;

void test_merge_maps_1()
{
Border_map a, b, c ;
std::cout << std::endl << "a" << std::endl ;
for (int i=1; i<10; i+=2)
{
    a.insert(std::pair<int, Cell>(i, Cell(i,i))) ;
    std::cout << i << " " ;
}

std::cout << std::endl << "b" << std::endl ;
for (int i=2; i<11; i+=2)
{
    b.insert(std::pair<int, Cell>(i, Cell(i,i))) ;
    std::cout << i << " " ;
}

std::cout << std::endl << "merge" << std::endl ;
std::merge(a.begin(), a.end(), b.begin(), b.end(), inserter(c,end(c))) ;

std::cout << "result" << std::endl ;
for(auto x: c)
    std::cout << x.first << " " ;
std::cout << std::endl ;
}

int main(void)
{
    test_merge_maps_1() ;
    return 0 ;
}
#包括
#包括
#包括
#包括
typedef-std::成对细胞;
typedef std::多地图边界\地图;
无效测试\u合并\u映射\u 1()
{
边界图a、b、c;
std::cout是,
multimap::begin()
返回一个普通(双方向)迭代器,但您需要一个能够进行插入的迭代器。您可以使用
std::inserter
模板从
迭代器
头获取一个:

#include <iterator>

/* ... */

std::merge(begin(m1),end(m1),begin(m2),end(m2),inserter(final_m,end(final_m)));
#包括
/* ... */
合并(开始(m1),结束(m1),开始(m2),结束(m2),插入器(final_m,end(final_m));
如您所见,
std::inserter
接受两个参数:需要插入迭代器的容器(即
final\m
),以及同一容器的普通迭代器,该迭代器用作插入的起点。由于合并操作的性质,为插入指定的起点应该是正在创建的多重映射的结尾。因此,我使用了
end(final_m)
(与
final_m.end()相同)作为第二个参数。

C++

#包括
#包括
使用std::map;
使用std::string;
地图lhs;
地图rhs;
insert(rhs.begin(),rhs.end());
C++17

#包括
#包括
使用std::map;
使用std::string;
地图lhs;
地图rhs;
左侧合并(右侧);

Nitpick:
multimap
是一个序列容器,它的迭代器必须至少是
ForwardIteratorS
而不是
inputiiterators
。如果使用随机迭代器,您最好使用问题中拒绝的插入解决方案。但是,使用end可能是正确的做法,因为merge将插入所有元素因此,使用end作为提示应该会给提问者带来想要的性能优势。@pmr True!或者实际上,我认为
std::multimap的
begin()
提供了标准所称的双向迭代器。
end(final\m)
是正确的迭代器,因为正如ymett所说,它是真正需要插入元素的点。在提供的迭代器是正确的插入点的情况下,
insert
保证摊销
O(1)
(表102——关联容器要求),这正是提问者所要求的。@SteveJessop是的,这是真的。我在帖子中已经说得更清楚了。(我最初的推理是,给算法的提示只与merge算法进行的第一次插入相关,因此不会对整个算法的复杂性产生影响。但无论如何,我同意使用
end()
是有意义的。)如果这是你的算法的结束,你应该考虑使用<代码>矢量< /代码>最后的结果。<代码>合并<代码>将生成一个有序的输出序列,而你在“<代码> > MultuaP
上所做的各种查询在排序<代码>矢量< /C>上都会更快。因为你知道所得到的序列的大小,也可以预处理。-使用
vector::reserve
进行分配。要获得更高的泛型性,只需接受
outputierator
作为参数并使用它。可能需要记录算法的空间复杂度,以便用户可以预分配内存。@pmr我相信我需要一个多重映射,因为内容是网格中的一个单元格(又名.std::pair),键是一个值(又名。double)。处理容器时,我需要按键(最低的第一个)拉出单元格。因为合并有序集(这里是multpmaps)在O(N)中,而排序在N.log(N)中,所以我更喜欢自下而上维护一个已排序的多映射表单,而不是随机打包数据并在请求时对其进行排序。@user1770724:an“有序向量”不是“随机打包数据并在请求时进行排序”。
merge
已按顺序输出结果,不需要单独的排序操作。pmr的要点是,在有序向量上查找通常更快(使用二进制搜索)所以,如果你不需要进行随机插入,向量就可以击败多重映射。
#include <iterator>

/* ... */

std::merge(begin(m1),end(m1),begin(m2),end(m2),inserter(final_m,end(final_m)));
#include <map>
#include <string>

using std::map;
using std::string;

map< string, string > lhs;
map< string, string > rhs;

lhs.insert( rhs.begin( ), rhs.end( ) );
#include <map>
#include <string>

using std::map;
using std::string;

map< string, string > lhs;
map< string, string > rhs;

lhs.merge( rhs );