我正在寻找一个像std :: multimap一样工作的STL容器,但我可以像vector一样按插入顺序访问成员。
例如:
multimap<char,int> mymultimap;
multimap<char,int>::iterator it;
mymultimap.insert ( pair<char,int>('a',100) );
mymultimap.insert ( pair<char,int>('z',150) );
mymultimap.insert ( pair<char,int>('b',75) );
mymultimap.insert ( pair<char,int>('a',75) );
for ( it=mymultimap.begin() ; it != mymultimap.end(); it++ )
cout << (*it).first << " => " << (*it).second << endl;
输出:
a =&gt; 100
a =&gt; 75
b =&gt; 75
z =&gt; 150
预期产出:
a =&gt; 100
z =&gt; 150
b =&gt; 75
a =&gt; 75
感谢。
答案 0 :(得分:2)
您可以使用std::vector<std::pair<char,int> >
。此外,您可以使用std::make_pair
函数创建一对。以下是示例代码:
vector<pair<char,int> > v;
vector<pair<char,int> >::iterator it;
v.push_back ( make_pair('a',100) );
v.push_back ( make_pair('z',150) );
v.push_back ( make_pair('b',75) );
v.push_back ( make_pair('a',75) );
for ( it=v.begin() ; it != v.end(); it++ )
cout << (*it).first << " => " << (*it).second << endl;
答案 1 :(得分:1)
boost库有一个灵活的多索引容器,可以执行您想要的操作以及更多内容:http://www.boost.org/doc/libs/1_43_0/libs/multi_index/doc/index.html
您可以构建可以按顺序访问的multi_index容器,但也允许O(log(N))快速查找。开始时语法有点不透明,但是一旦你得到了一些工作,这是一项值得的投资,因为实现将由boost人员和大量普通用户进行全面测试。
答案 2 :(得分:0)
除了已经建议的std::vector<std::pair<char,int> >
之外,boost::bimap可能是一个很好的解决方案。
答案 3 :(得分:0)
您可以将multimap
与list
合并。
以下是一个可以满足您需求的容器。对象存储在multimap
和其他list
存储多图迭代器中(只要指向的元素在容器中,它们就保持有效)。所有操作都具有与multimap
相同的复杂性,除了{em> O(n * m)的erase
方法,其中 n 是所有元素的数量, m 是删除的元素数。
#include <map>
#include <list>
#include <algorithm>
template <class Key, class T>
class my_map : public std::multimap<Key, T> {
public:
typedef typename std::multimap<Key, T> multimap_type;
typedef typename multimap_type::key_type key_type;
typedef typename multimap_type::value_type value_type;
typedef typename multimap_type::size_type size_type;
typedef typename multimap_type::iterator iterator;
struct order_iterator : std::list<typename multimap_type::iterator>::iterator {
typedef typename std::list<typename multimap_type::iterator>::iterator iterator_t;
order_iterator() {}
order_iterator(const iterator_t &iterator) : iterator_t(iterator) { }
const std::pair<const Key, T>& operator * () const { return ***(const iterator_t*)this; }
std::pair<const Key, T>& operator * () { return ***( iterator_t*)this; }
const std::pair<const Key, T>* operator -> () const { return &**this; }
std::pair<const Key, T>* operator -> () { return &**this; }
};
private:
std::list<typename multimap_type::iterator> list;
multimap_type *base() { return this; }
public:
order_iterator order_begin() { return this->list.begin(); }
order_iterator order_end() { return this->list.end(); }
iterator insert(const value_type& x)
{
iterator ret = this->base()->insert(x);
this->list.push_back(ret);
return ret;
}
iterator insert(iterator position, const value_type& x)
{
iterator ret = this->base()->insert(position, x);
this->list.push_back(ret);
return ret;
}
template <class InputIterator>
void insert(InputIterator first, InputIterator last)
{
while (last != first) this->insert(first++);
}
void erase(iterator first, iterator last)
{
if (first == this->end()) return;
for (iterator it = first; it != last; ++it) {
this->list.erase(std::find(this->list.begin(), this->list.end(), it));
}
}
void erase(iterator position)
{
iterator last = position;
this->erase(position, ++last);
}
size_type erase (const key_type& x)
{
iterator range_begin = this->lower_bound(x);
if (range_begin == this->end()) return 0;
size_type ret = 0;
iterator range_end = range_begin;
do range_end++, ret++; while (range_end != this->end() && range_end->first == x);
this->base()->erase(range_begin, range_end);
for (; range_begin != range_end; range_begin++) {
this->list.erase(std::find(this->list.begin(), this->list.end(), range_begin));
}
return ret;
}
void clear()
{
this->list.clear();
this->base()->clear();
}
};
#include <iostream>
using namespace std;
my_map<char,int> mymultimap;
void dump()
{
cout << "by insert:\n";
for (
my_map<char,int>::order_iterator it = mymultimap.order_begin();
it != mymultimap.order_end();
it++
) {
cout << (*it).first << " => " << (*it).second << endl;
}
cout << "by key:\n";
for (
my_map<char,int>::iterator it = mymultimap.begin();
it != mymultimap.end();
it++
) {
cout << (*it).first << " => " << (*it).second << endl;
}
cout << endl;
}
int main()
{
mymultimap.insert(make_pair('a',100));
mymultimap.insert(make_pair('z',150));
mymultimap.insert(make_pair('b',75));
mymultimap.insert(make_pair('a',75));
dump();
mymultimap.erase('a');
dump();
}
如果更频繁地使用插入顺序中的迭代元素然后通过键进行查找,那么“镜像”该想法将更为理想:将键/值对存储在list
中(因此我们可以迭代插入()并且还有multiset
个包含list
个元素的迭代器(用于按键查找)。