0

I've need a solution, which will store a non unique key - values pairs. I don't want to repeat keys (space efficiency) and I want to focus on lookup speed (efficiency of inserting a new data is less important). I will use std::multimap here. But I will have to lookup for keys, which meets some range criteria.

The most complex example: Key is a string, values are not important. I'd like to find out all values, which keys starts with "Lol". Or I'd like to find out all values, which keys "are between" "bar" and "foo".

Can I do it with a multimap? My second thought is to use sorted vector, which will point to vectors of values. Something like that:

std::vector<std::string, std::vector<T>> sorted_vec;

Then I can easily meet search criteria. But I really care about a performance of lookups. Is it a right approach?

Dejwi
  • 4,393
  • 12
  • 45
  • 74
  • It sounds like an ordered map of vectors is more along the line you're describing, but I'm not sure it is versatile enough for you. – WhozCraig Apr 07 '13 at 01:03
  • If insertion is not important, I think ``vector`` will be preferred than ``map`` 'cause the latter is rb-tree based. ``struct foo {}; vector;`` might be OK. – gongzhitaao Apr 07 '13 at 01:04

3 Answers3

2

Yes, you can use std::multimap. And to complete your range bases query, you can use the two algorithms std::lower_bound and std::upper_bound in the header file algorithm.

  • I think I made a mistake on lower_bound and upper_bound.The two algorithms are not effective for multimap iterator. Use multimap::lower_bound and multimap::upper_bound instead. – Expressway Retrograding Apr 07 '13 at 04:57
  • First, as Dejwi needs "keys are between bar and foo" - then [equal_range](http://en.cppreference.com/w/cpp/container/multimap/equal_range) would be better than lower_bound + upper_bound. Second, as he "really care about a performance of lookups" - multimap is poor choice - sorted vector would be faster due to better locality. – Evgeny Panasyuk Apr 08 '13 at 14:26
1

Or I'd like to find out all values, which keys "are between" "bar" and "foo".

If you have Boost, I would recommend to use boost::flat_map (it just header-only library) - it maintains sorted vector inside. Generally, it has better lookup than std::map due to better compactness/locality.

Otherwise use

vector<pair<string,value>>
or
vector<pair<string,vector<value>>> //(for re-use of keys)
// instead of pair, you may use just struct if you concerned with lexicographical compare

plus std::sort

plus std::equal_range/lower_bound

Community
  • 1
  • 1
Evgeny Panasyuk
  • 9,076
  • 1
  • 33
  • 54
0

You should use a Patricia trie.

There's one in libstdc++, though it's nonstandard.

If you're going to stick with standard containers, I think your sorted vector solution is best.

tmyklebu
  • 13,915
  • 3
  • 28
  • 57