在std :: map上进行二进制搜索

时间:2014-04-16 22:59:56

标签: c++ c++11 map binary-search

我有一张数据地图,关键是std :: string。我想对它执行二进制搜索,但我不能只使用std :: map :: find(),因为我只提供密钥的一部分。

假设我有一张包含数据的地图:

["abc"] -> ...
["efg"] -> ...
["ijk"] -> ...
["iik"] -> ...

我希望能够搜索到这一点,假设只提供“i”并且它应该返回

  

[“ijk”] - > ...,[“iik”] - > ...

这可能吗?我试图使用迭代器来做到这一点,但我失败了,因为我不能将它们视为索引。

注意:由于其他原因,我将数据保存在地图中,因此我不想将其更改为其他数据结构。

3 个答案:

答案 0 :(得分:5)

这是可能的,但您不需要实际二进制搜索数据。

您可以使用lower_bound查找第一个元素,然后推进生成的迭代器,直到您的密钥不再符合您的条件,将它们存储在<vector>或类似容器中以全部返回。

答案 1 :(得分:3)

map::lower_bound()会帮助你。

答案 2 :(得分:0)

我根据map::lower_bound()lccarrasco的建议,基于Michael Burr构建了一个解决方案。此函数为您要查找的地图中的第一个元素提供迭代器。该函数执行二进制搜索,因为其复杂度为对数。

然后,只要要查找的字符串是映射中值的前缀,就必须推进提供的迭代器。 One way正在使用string::compare()

为清楚起见,我选择int作为您的地图的价值。请用您的数据类型替换它。总的来说,代码如下:

int main() {
    std::map <std::string, int> myMap{ {"abc", 1}, {"efg", 2}, {"ijk", 3}, {"iik", 4} };
    std::string prefix("i");

    for (auto it = myMap.lower_bound(prefix); it != std::end(myMap) && it->first.compare(0, prefix.size(), prefix) == 0; ++it)
        std::cout << it->first << " -> " << it->second << std::endl;

    return 0;
}

输出:

  

iik-> 4
  ijk-> 3

Code on Ideone