在std :: map中搜索限制搜索值的键

时间:2018-08-18 21:46:20

标签: c++ stdmap

假设我有std::map<std::pair<int, int>, int>,并且在map中的键是一对两个整数值。

是否可以找到一个限制我要查找的值的键?

例如:如果地图包含:

key = {4, 9}

我能否基于x大于4而x小于9来找到此密钥?其中x是一些整数值。

我希望这是有道理的。

3 个答案:

答案 0 :(得分:2)

std::map具有一个find()函数,该函数仅查找完全匹配项,因为该键被视为单个值(即使作为地图包含多个元素也是如此)。

但是,根据您要实现的目标,有两种候选解决方案:

1)使用equal_range()

equal_range()将为您提供由两个迭代器定义的范围。第一个指向不小于key的元素,第二个指向大于key的第一个元素。

因此,如果您要查找与确切键相关的界限,则可能是您要查找的:

auto r2 = m.equal_range ({1,2});
if (r2.first!=m.end()) {
    std::cout<<"Found range1 -> "<< r2.first->second << std::endl;
}
if (r2.second!=m.end()) {
    std::cout<<"Found range2 -> "<< r2.second->second << std::endl;
}
//attention the r2.first==r2.second if exact value not found. 

如果仅使用该对中的第一个成分来寻找界限,则不会为您提供部分搜索。但是您可以使用它来搜索对(x,0);这将比仅遍历整个地图更为有效。

auto r3 = m.equal_range ({x,0});
for (auto r=r3.first; r!=m.end() && r->first.first==x; r++) {
    std::cout<<"In range -> "<< r->second << std::endl;
}
std::cout<<"That's all I found for <<x<<std::endl;

这里是online demo

2)使用地图

如果您的问题与部分键有关,而您只知道第一个元素,那么使用std::map<int, std::map<int, int>>可能会更容易。

然后将简化对部分键的搜索:

auto r3 = m.find (x);   // look for first component
if (r3==m.end()) 
    std::cout<<"r3 not found"<<std::endl; 
else for (auto r : r3->second) {  // iterate on second component
    std::cout<<"In range -> "<< r.second << std::endl;
}

然而,这种简单性是以牺牲全键搜索为代价的,这是因为您需要首先寻找第一个组件,然后寻找第二个组件。

Demo code

答案 1 :(得分:2)

如果间隔不重叠,则可以by using a slightly different map, utilising a transparent comparator

std::map<std::pair<int, int>, int, std::less<>> themap;

令人高兴的是,现在比较是透明的,因此我们可以制作自己的类型来为我们做正确的事情:

struct target
{
    int value;
};
constexpr bool operator<(target a, std::pair<int, int> b) noexcept {
    return a.value <= b.first;
}
constexpr bool operator<(std::pair<int, int> a, target b) noexcept {
    return a.second <= b.value;
}

themap.find(target{value});

答案 2 :(得分:0)

您可以使用std :: find_if算法。检出this example on ideone

--save

映射可以视为成对的 vector ,并且可以在算法库中的函数中使用。如果find_if匹配谓词(签名#include <algorithm> #include <iostream> #include <map> #include <tuple> int main() { std::map<std::pair<int, int>, int> m { { {1,3}, 4 }, { {6, 10}, 5 }, { {123, 126}, 111 } }; int x = 8; auto result = std::find_if(std::begin(m), std::end(m), [x](const auto& v) { return v.first.first < x && x < v.first.second; }); if(result != std::end(m)) { std::cout << "FOUND x " << result->second; } return 0; } ),则将迭代器返回到元素。在您的情况下,类型为bool pred(const Type &a);