【问题标题】:How to find object in container by value, not key如何按值而不是键在容器中查找对象
【发布时间】:2015-07-28 13:50:47
【问题描述】:

我有一个map<int, int*>

我想在map 中搜索特定值(不是键),并检索指向正确int*(映射值)的迭代器

我可以使用std::find_if() 吗?

auto it = std::find_if(map.begin(), map.end(), compare);

比较应该是这样的:

bool compare(int* v1, int* v2)
{
 return (v1==v2);
}

最好的方法是什么?

【问题讨论】:

标签: c++ c++11 containers


【解决方案1】:

你可以这样做:

#include <string>                                                                                                                                                                                                                           
#include <iostream>
#include <algorithm>
#include <map>

int main()
{
    std::map<int, std::string> m = {{1, "a"}, {2, "b"}};
    std::string value_to_find = "b";
    auto it = std::find_if(m.begin(), m.end(), [&](decltype(m)::value_type &v) {
        return v.second == value_to_find;
    });

    if (it != m.end()) {
        std::cout << it->first << std::endl;
    }
    return 0;
}

你可以直接使用模板实例代替decltype()

[&](std::map<int, std::string>::value_type &v)

【讨论】:

  • 或使用 C++14,[&amp;](auto&amp; v){...}
  • @Creris 是的,但问题标记为c++11。非常感谢c++14的自动类型推导。
  • @Daniel 是的,可能是对某些东西感到困惑。我的意思是,使用无序容器效率低下。
  • @VictorPolevoy 您的解决方案的时间复杂度仍然是线性的,因为std::find_if 基本上是一种线性时间算法。如果您想实现亚线性时间复杂度,则需要使用期望有序范围的算法。
  • @VictorPolevoy 没有看到使用有序容器如何更有效;有序容器的顺序是键,而不是值。
【解决方案2】:

std::find_if 可以为任何“类似地图”的类型完成这项工作,例如std::mapstd::unordered_map。请注意,集合确实不需要需要订购;任何定义InputIterator(即“可迭代”)的东西都可以。

这是一个适用于任何“类似地图”(但不是“类似多地图”)的函数

template <typename MapType>
typename MapType::const_iterator find_value(const MapType& map, const typename MapType::mapped_type& value)
{
    return std::find_if(std::cbegin(map), std::cend(map), [&value] (const auto& p) { return p.second == value; });
}

int main(int argc, const char **argv)
{
    std::unordered_map<int, char> map {{0, 'A'}, {1, 'B'}, {2, 'C'}};
    char val {'B'};
    auto it = find_value(map, val);
    if (it != std::cend(map)) std::cout << it->first << std::endl;
    return 0;
}

你应该知道这是一个线性时间算法(不管地图是否有序),因此如果这是一个你会经常使用的操作,你应该考虑是否更好也只存储逆映射。

【讨论】:

  • 你在lamba的参数列表中使用auto,而这个问题是关于c++11
猜你喜欢
  • 2018-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-25
  • 2023-03-22
  • 2016-01-08
  • 2019-03-02
  • 2019-04-01
相关资源
最近更新 更多