我的项目涉及分而治之策略,以便对现有算法进行分析。
算法返回std::multimap<int, std::pair<int, int>>
。上面是一个preilinary(single_thread)版本的草图。
typedef std::multimap<int, std::pair<int, int>> Map ;
struct Box
{
std::pair<int, int> top_left, bottom_right ;
}
Map my_algo(Box, a_box)
{
Map final_m ;
if (not is_small(a_box))
{
box b1, b2 ;
split_box(a_box, &b1, &b2) ; // this function divides the box in two halves
Map m1 = my_algo(b1) ;
Map m2 = my_algo(b2) ;
// this line will not compile. final_m.begin() is not accepted.
std::merge (m1.begin(), m1.end(), m2.begin(), m2.end(), final_m.begin()) ;
}
return final_m ;
}
我知道我可以使用insert或merge来进行合并(如here所述)。但是插入在O(N.Log(n))中,而合并在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 ;
}
答案 0 :(得分:5)
是的,multimap<T>::begin()
返回一个普通(双向)迭代器,但是你需要一个能够插入的迭代器。您可以使用std::inserter
标题中的iterator
模板获取一个:
#include <iterator>
/* ... */
std::merge(begin(m1),end(m1),begin(m2),end(m2),inserter(final_m,end(final_m)));
如您所见,std::inserter
有两个参数:您需要插入迭代器的容器(即final_m
),以及同一容器的普通迭代器,它用作起点插入。由于合并操作的性质,插入的起点应该是正在创建的多地图的 end 。因此,我使用end(final_m)
(与final_m.end()
相同)作为第二个参数。
答案 1 :(得分:1)