在无序的多映射中循环
Iterating through an unordered multimap
我在我的无序多重映射中插入了一些元素,我正在使用相等的范围找到映射到键k的所有值。现在我想按插入顺序遍历这些映射值。查看代码以更好地理解。
#include <iostream>
#include <unordered_map>
using namespace std;
int main()
{
unordered_multimap<int,int> m;
m.insert(make_pair(1,2));
m.insert(make_pair(1,3));
m.insert(make_pair(1,4));
auto it = m.equal_range(1);
for(auto it1 = it.first; it1 != it.second; it1++) {
cout<<it1->second<<endl;
}
}
输出:
4
3
2
但我希望按照插入键和映射值的顺序进行遍历。所以,我想按2,3,4的顺序遍历。有可能吗?
没有一种简单的方法可以满足您的要求。当元素被插入有序或无序的多映射中时,它们实际上被放置在内部结构中,并且不知道它们是按哪个顺序放置的。
您应该有一个辅助容器,例如std::queue
容器,用于将迭代器附加到插入的元素。迭代器可以从插入中获得如下:
auto inserted_pos = m.insert(make_pair(1,4));
请记住,迭代器在插入过程中不会失效。如果元素被删除,则它们将无效,并且仅对相关元素无效。
这里有一种实现您想要的东西的方法。
它使用了boost::multi_index
提供的一些技术。
注意使用project
将一个索引中的迭代器转换为另一索引中的迭代器。
#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/member.hpp>
namespace example {
struct by_id {};
struct by_insertion_order {};
using namespace boost;
using namespace boost::multi_index;
using item_type = std::pair<int, int>;
typedef multi_index_container<
item_type, // what we are storing
indexed_by<
// unordered multimap-type index
hashed_non_unique<tag<by_id>, member<item_type, int, &item_type::first> >,
// sequence-type index - records insertion order
sequenced<tag<by_insertion_order>>
>
> my_store;
using const_insertion_sequence_iterator = decltype(std::declval<my_store>().get<by_insertion_order>().cbegin());
using const_by_id_iterator = decltype(std::declval<my_store>().get<by_id>().cbegin());
// convert a range of 'by_id' iterators to an ordered vector 'by_insertion_sequence' iterators
// @param store is a reference to the store for which the iterators are valid
// @param first is the first by_id iterator in the filtered range
// @param last is the 'one past the end' iterator of the filtered range
// @returns a vector of iterators to items ordered by insertion sequence
auto
projected_to_insertion_order(const my_store& store,
const_by_id_iterator first,
const_by_id_iterator last)
-> std::vector<const_insertion_sequence_iterator>
{
std::vector<const_insertion_sequence_iterator> result;
for ( ; first != last ; ++first) {
result.push_back(store.project<by_insertion_order>(first));
}
sort(result.begin(),
result.end(),
[&store](const auto& il, const auto& ir) {
return distance(store.get<by_insertion_order>().cbegin(), il)
< distance(store.get<by_insertion_order>().cbegin(), ir);
});
return result;
}
}
int main()
{
using namespace std;
using example::my_store;
using example::by_id;
using example::by_insertion_order;
using example::projected_to_insertion_order;
// define store
my_store m;
// add some items
m.get<by_id>().emplace(1,2);
m.get<by_id>().emplace(3,6);
m.get<by_id>().emplace(1,3);
m.get<by_id>().emplace(2,5);
m.get<by_id>().emplace(1,4);
// get range of items filtered by id
auto ip = m.get<by_id>().equal_range(1);
cout << "filtered but unorderedn";
for (auto it = ip.first ; it != ip.second ; ++it) {
cout << it->first << ":" << it->second << endl;
}
// project that to a vector of iterators to items ordered by insertion sequence
cout << "filtered and ordered by insertion sequencen";
for (const auto& it : projected_to_insertion_order(m, ip.first, ip.second)) {
cout << it->first << ":" << it->second << endl;
}
}
预期输出:
filtered but unordered
1:4
1:3
1:2
filtered and ordered by insertion sequence
1:2
1:3
1:4
相关文章:
- 在映射擦除c++期间执行循环的次数
- 与多个 for 循环与单个 for 循环 wrt 相关的性能从多映射获取数据
- 迭代嵌套映射与范围为循环:没有名为"first"的成员
- 映射中循环的迭代器
- 为什么这个 x 值在这个循环映射中没有增加?C++
- 在循环(C++)中用新指针填充映射
- c++ 在循环中删除迭代器(映射的映射)
- 遍历 STL 映射(集/多集)的最佳方法,同时元素可能会在循环期间被删除并重新插入?
- 映射基于自动的循环单元素访问C++
- 有没有办法在不使用循环的情况下非具体地引用映射中的每个值?C++
- 在 stl 映射和列表 (c++) 上进行迭代的泛型循环
- C++:分段函数,循环初始化为映射
- c++ 过期映射条目线程与事件循环
- 我如何将输入分配给在 for 循环中设置的映射功能
- 循环访问提升mapped_region/内存映射文件
- 复制地图<双精度,元组<双精度,双精度>>映射<双精度,双精度>没有循环?
- 在使用无序多映射实现的有向图中查找循环
- 循环访问映射并删除动态分配的元素
- 不带迭代程序的哈希映射循环
- 如何在映射向量中循环访问地图