【问题标题】:Find if vector contains pair with second element equal to X查找向量是否包含第二个元素等于 X 的对
【发布时间】:2014-06-04 04:02:06
【问题描述】:

我有这个向量:

using namespace std;

vector< pair<short, string> > vec = {};

我想知道是否存在一对&lt;a, b&gt;b == X

我从&lt;algorithm&gt; 知道std::find,但不知道如何在这里应用它。

我应该编写自己的函数来做到这一点吗?

bool is_in_vec(X)
{
    for (auto& e : vec)
        if (e.second == X)
            return true;
    return false;
}

这样有效率吗?

【问题讨论】:

    标签: c++ algorithm c++11 search coding-efficiency


    【解决方案1】:

    如果您只想知道是否存在满足您标准的元素,您的解决方案看起来不错。我会在循环中使用const 引用,因为循环不应该改变向量的元素:

    for (const auto& e : vec) ....
    

    如果你想使用标准库算法,可以试试std::find_if

    const std::string X{"foobar"};
    
    auto it = std::find_if(vec.begin(), 
                           vec.end(), 
                          [&X](const pair<short, string>& p)
                          { return p.second == X; });
    

    这里,it 是第一个满足条件的元素的迭代器,如果没有找到元素,则等于 vec.end()

    【讨论】:

    • 您的解决方案是否使用 const 引用?
    • 谢谢,这正是我想要的。
    • @sehe:我的意思是捕获。我只是有点讽刺。
    • @user2672165 现在是const :-) 我的理解是,当裁判在其上下文中不是const 时,没有机制可以捕获为“对const 的引用”被捕获。
    • @sehe 引用捕获总是非常量的;它是默认情况下为const 的按值捕获(因为lambda 的operator()const,除非将lambda 声明为mutable)。
    【解决方案2】:

    事实上,如果您可以根据second 字段对vector 对进行排序,则实际上您可以吃蛋糕。

    在这种情况下,您最终会重新发明 Boost 所称的 flat_(multi_)map。明显的好处是搜索可以在 O(log(n)) 时间内完成,而不是线性时间。

    Live On Coliru

    using namespace std;
    
    #include <utility>
    #include <vector>
    #include <string>
    #include <algorithm>
    
    typedef std::pair<short, std::string> Pair;
    
    struct Cmp 
    {
        bool operator()(Pair const& a, Pair const& b) const { return a.second < b.second; };
        bool operator()(Pair const& a, std::string const& b) const { return a.second < b; };
        bool operator()(std::string const& a, Pair const& b) const { return a < b.second; };
    };
    
    int main()
    {
        std::vector<Pair> vec = { 
            { 1, "aap" }, 
            { 2, "zus" }, 
            { 3, "broer" }
        };
    
        Cmp cmp;
        std::sort(vec.begin(), vec.end(), cmp);
    
        auto it = std::binary_search(vec.begin(), vec.end(), std::string("zus"), cmp);
    
        std::cout << it->first << ": " << it->second << "\n";
    }
    

    打印

    2: zus
    42: zus
    

    【讨论】:

    • +1,但我相信你的意思是 flat_(multi)map,而不是 flat_(multi_)map ;)
    【解决方案3】:

    在 C++11 中,您也可以使用 std::any_of

    std::string X{"foobar"};
    return std::any_of(vec.begin(), vec.end(),
                       [&X](const pair<short, string>& p)
                       { return p.second == X; });
    

    【讨论】:

      【解决方案4】:

      我认为您应该改用std::map,这将提供一个高效的std::map::find 成员函数:

      std::map<std::string, short>
      // …
      auto it = map.find(X);
      

      这与这种查找一样有效(保证为O(log(N)))。

      【讨论】:

      • +1 用于观察。即食即食的方法现在在my answer 中。
      猜你喜欢
      • 2019-11-06
      • 2011-01-10
      • 1970-01-01
      • 2019-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多