如何获得"之前的#34;的迭代器(或值) std :: multimap的给定键的项目?

时间:2014-12-22 22:48:33

标签: c++ std multimap

对于我的std::multimap,我想获得之前给出密钥的项目。

对于在给定键之后的项目,我可以简单地使用std::multimap::upper_bound(它将返回键大于给定的元素)。但不幸的是,std::multimap::lower_bound会返回带有"低或等于"的元素。键。

取自http://www.cplusplus.com/reference/map/multimap/lower_bound/的样本:

mymultimap.insert(std::make_pair('a',10));
mymultimap.insert(std::make_pair('b',121));
mymultimap.insert(std::make_pair('c',1001));
mymultimap.insert(std::make_pair('c',2002));
mymultimap.insert(std::make_pair('d',11011));
mymultimap.insert(std::make_pair('e',44));

itlow = mymultimap.lower_bound ('b');  // itlow points to b
itup = mymultimap.upper_bound ('d');   // itup points to e (not d)

当您将a作为参数时,如何获取b的迭代器(或值)?

3 个答案:

答案 0 :(得分:5)

您可以使用lower_bound,但必须考虑两个边缘情况:它返回begin()并返回end()

auto itfound = mymultimap.lower_bound('b');
if (itfound == mymultimap.begin()) {
    // 'b', or something past 'b', is the first item
    // or the map is empty
    // what to do here?
}
else if (itfound == mymultimap.end()) {
    // there does not exist an item >= 'b'
    // what to do here? possibly std::prev(end()) ?
}
else {
    // ok cool, we found something in the middle
    // just back up
    --itfound;

    // do stuff with itfound here
}

答案 1 :(得分:2)

继续使用lower_bound,然后递减你收到的迭代器(在检查后确保它不是begin)。

itfound = mymultimap.lower_bound('b');
if (itfound != mymultimap.begin())
{
    --itfound;
    // do something with itfound
}

如果项目不在地图中,您可能需要稍微不同的逻辑,但这不应该是一个难以修改。

答案 2 :(得分:1)

对于任何有序的容器(即mapsetmultimapmultiset),我们知道以下内容:

  • lower_bound(key)返回第一个条目> = key
  • upper_bound(key)返回第一个条目> key

如果没有条目> = />,每个函数也会返回end()key

所以我们有基于运营商的功能>和> =。我们可能会合理地问,我们是否可以基于<和< =以及?

要求第一个条目<或< = key(这是容器中的begin()或不是key。然而,要求最后这样的条目是有意义的。实际上,你要求的是最后一个条目< key
为了完整起见,我们也会考虑最后一个条目< = end()

假设我们有这样的功能,如果没有这样的条目他们该怎么办?我们可以比返回lower_bound做得更糟 - 它是一个可测试的值,与任何成功案例都不同。它还与upper_boundfind以及<algorithm>以及end()标头中的大量独立搜索功能一致。最重要的是,lower_bound(key)通常用于表示“没有这样的条目”。所以这对我们来说也应该足够好了。

正如巴里和马克所指出的那样,调用lower_bound(key) == begin()然后递减会给我们想要的东西,除非key。在这种情况下,第一个(因此[联合 - ]最小)条目是> = key,因此没有条目&lt; end() - 正是我们刚刚说过的情况我们应该返回key

对于查找最后一个条目&lt; = upper_bound的情况,我们可以使用end()执行相同操作,再次返回upper_bound(key) == begin()表示没有此类条目&#39 39;何时lower_bound_dec

让我们分别调用这些函数upper_bound_dec// Find the last entry < key, returning end() if all entries are >= key // Container can be any that implements lower_bound, e.g. std::map, std::multimap, std::set or std::multiset template<typename Container, typename Key> typename Container::const_iterator lower_bound_dec(const Container &container, const Key &key) { auto it = container.lower_bound(key); if (it == std::begin(container)) it = std::end(container); else --it; return it; } // Find the last entry <= key, returning end() if all entries are > key // Container can be any that implements upper_bound, e.g. std::map, std::multimap, std::set or std::multiset template<typename Container, typename Key> typename Container::const_iterator upper_bound_dec(const Container &container, const Key &key) { auto it = container.upper_bound(key); if (it == std::begin(container)) it = std::end(container); else --it; return it; }

std::lower_bound

我们也可以定义基于迭代器的函数,镜像std::upper_bound// Find the last entry < key, returning end() if all entries are >= key // last must be reachable from first, and all entries in sorted order between them template<typename Iterator, typename Key> Iterator lower_bound_dec(Iterator first, Iterator last, const Key &key) { auto it = container.lower_bound(first, last, key); if (it == first) it = last; else --it; // requires bidirectional iterators return it; } ,并且可以使用双向迭代器对任何已排序的范围进行操作:

upper_bound(first, last, key)

begin()以及将比较器留给练习者的表格留给读者/任何想要通过编辑获得代表的人! :)

<强> TL / DR 使用lower_bound然后递减,但需要注意&#34;递减&#34; end()会产生big_task表示没有此类条目。&#39;