【问题标题】:Visual C++ hash_multimap not finding any resultsVisual C++ hash_multimap 没有找到任何结果
【发布时间】:2010-08-09 23:06:34
【问题描述】:

我需要一些帮助来理解 stdext::hash_multimap 的 lower_bound、upper_bound 和 equal_range 是如何工作的(至少是 VS2005 版本)。

我有以下代码(为问题总结)

#include <hash_map>

using stdext::hash_multimap;
using std::greater;
using stdext::hash_compare;
using std::pair;
using std::cout;

typedef hash_multimap < double, CComBSTR, hash_compare< double, greater<double> > > HMM;
HMM hm1;
HMM :: const_iterator it1, it2;
pair<HMM::const_iterator, HMM::const_iterator> pairHMM;

typedef pair <double, CComBSTR> PairDblStr;

// inserting only two values for sample
hm1.insert ( PairDblStr ( 0.224015748, L"#1-64" ) );
hm1.insert ( PairDblStr ( 0.215354331, L"#1-72" ) );

// Using a double value in between the inserted key values to find one of the elements in the map
it1 = hm1.lower_bound( 0.2175 );

if( it1 == hm1.end() )
{
    cout << "lower_bound failed\n";
}

it1 = hm1.upper_bound( 0.2175 );

if( it1 == hm1.end() )
{
    cout << "upper_bound failed\n";
}

pairHMM = hm1.equal_range( 0.2175 );
if( ( pairHMM.first == hm1.end() ) && ( pairHMM.second == hm1.end() ) )
{
    cout << "equal_range failed\n";
}

正如评论中提到的,我传入的值 (0.2175) 介于两个插入的键值 (0.224015748、0.215354331) 之间。但是代码的输出是:

lower_bound failed
upper_bound failed
equal_range failed

我是否误解了如何在地图中使用 lower_bound、upper_bound 和 equal_range?我们不能使用这些方法找到“最接近的匹配”键吗?如果这些方法不合适,您对我可以使用什么来满足我的要求有什么建议吗?

提前感谢您的帮助。

感谢@billy-oneal @dauphic 的 cmets 和编辑。我已经更新了上面的代码,使其可编译和可运行(当然,一旦包含正确的标头)。

【问题讨论】:

  • 您发布的代码无法编译,您能否修复它,以便我们再次检查您是否正确使用它?例如if( it1 = hm1.end() )it1 = hm1.upper_bound( 0.2175 ); 之后的行
  • 将标签更改为 visual-c++,因为标准 C++ 没有 hash_multimap 类型。
  • C++0x 等价物是 unordered_multimap
  • @dauphic。感谢您的建议。更新的代码已发布。

标签: visual-c++ stl


【解决方案1】:

我们不能使用这些方法找到“最接近的匹配”键吗?

没有。 hash_multimap 是使用哈希表实现的。彼此非常接近的两个键(例如 0.2153 和 0.2175)可能会映射到哈希表中完全不同的 bin。

哈希表不会按排序顺序维护其元素,因此如果不进行线性搜索,您将无法找到与给定键最接近的匹配项。

hash_multimap 中的 lower_boundupper_boundequal_range 函数在 Visual C++ 标准库扩展中的实现有些奇怪。

考虑the documentation for lower_bound

成员函数确定受控序列中的第一个元素X,该元素散列到与key相同的桶中,并且与key具有等效的排序。如果不存在这样的元素,则返回hash_map::end;否则返回一个指定X 的迭代器。您可以使用它来定位当前在受控序列中与指定键匹配的元素序列的开头。

还有the documentation for upper_bound

成员函数确定受控序列中的最后一个元素X,该序列散列到与key相同的桶中,并且与key具有等效的排序。如果不存在这样的元素,或者X是受控序列中的最后一个元素,则返回hash_map::end;否则它返回一个迭代器,该迭代器指定X 之外的第一个元素。您可以使用它来定位当前在受控序列中与指定键匹配的元素序列的末尾。

本质上,这些函数允许您识别具有给定键的元素范围。他们的行为std::lower_boundstd::map::lower_bound 的行为相同(他们的行为是您所期望的)。

无论如何,C++0x 无序关联容器不提供 lower_boundupper_boundequal_range 函数。

您对我可以使用什么来满足我的要求有什么建议吗?

是的:如果您需要 lower_boundupper_bound 的行为,请使用像 std::multimap 这样的有序关联容器。

【讨论】:

  • @james-mcnellis 感谢您的回答。您使用 std::multimap 而不是 stdext::hash_multimap 的建议有效。我认为这三种方法做我认为的原因是因为以下 MSDN 页面:bit.ly/aAGAlkbit.ly/ammaLF,它们与您发布的不同 - 您发布的那些似乎是用于 CLR(即托管代码,而不是本机代码)。我发布的文档与我在本地 MSDN 安装中的文档相同。微软似乎存在文档缺陷。但是您的解释足以解决我的问题。
  • @ossandcad:哦,对不起。我引用了hash_map 文档,而不是hash_multimap 文档。是的,hash_multimap 文档充其量只是误导。它说它返回一个迭代器,“如果没有找到与键匹配的位置,则该迭代器会处理 hash_multimap 中最后一个元素之后的位置。”因此,如果未找到与该键匹配的内容,则返回 end()。不过,这句话的第一部分(我没有在这里引用)相当混乱。
猜你喜欢
  • 2021-01-10
  • 1970-01-01
  • 1970-01-01
  • 2013-03-27
  • 2018-08-31
  • 1970-01-01
  • 1970-01-01
  • 2013-11-25
  • 2019-12-21
相关资源
最近更新 更多