【问题标题】:How to search in vector of structure by a structure attribute?如何通过结构属性在结构向量中搜索?
【发布时间】:2018-03-26 09:34:00
【问题描述】:

我有一个基于变量排序的结构向量。

例如:

struct Client {
string name;
int sm_index;
int client_id;
int user_id;

Client(string str, int x,  int y,  int c) : name(str), sm_index(x), client_id(y),user_id(c){}
}

根据sm_index

排序

我如何找到并获取 sm_index 与我们的目标结构匹配的结构的数据。

我们有以下向量,没有。添加到其中的结构。

例如:

vector <client> CLIENT;

    CLIENT.push_back(Client("Rahul",8,1,13));
    CLIENT.push_back (Client("Sahil",12,3,12));
    CLIENT.push_back (Client("Ramesh",1,4,11));
    CLIENT.push_back (Client("Suresh",5,5,10));
    CLIENT.push_back (Client("Ganesh",86,6,9));
    CLIENT.push_back (Client("Gagan",4,7,8));

如何找到sm_index值为5的结构体。

我尝试了 find() 函数,但无法理解如何使用它。

【问题讨论】:

  • std::find_if 与合适的函子一起使用或lambda
  • find_if(CLIENT.cbegin(), CLIENT.cend(), [](const auto&amp; v) { return v.sm_index == 5; }
  • 如果CLIENT 具有实体语义,则覆盖operator== 是有意义的,并允许std::find 搜索特定客户。
  • 您说“基于sm_index 排序”,但在您的示例中,向量未按sm_index 排序。向量是否已排序会影响使用哪种算法。
  • 我的向量使用以下代码根据 sm_index 进行排序:std::sort(CLIENT.begin(), CLIENT.end());重载 bool operator

标签: c++ search vector find structure


【解决方案1】:

基于Yola,这里有一个现成的代码sn-p

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

struct Client {
    std::string name;
    int sm_index;
    int client_id;
    int user_id;

    Client(std::string str, int x,  int y,  int c)
        : name(str), sm_index(x), client_id(y), user_id(c)
    {}
};

int main()
{
    std::vector<Client> CLIENT;

    CLIENT.push_back(Client("Rahul",8,1,13));
    CLIENT.push_back(Client("Sahil",12,3,12));
    CLIENT.push_back(Client("Ramesh",1,4,11));
    CLIENT.push_back(Client("Suresh",5,5,10));
    CLIENT.push_back(Client("Ganesh",86,6,9));
    CLIENT.push_back(Client("Gagan",4,7,8));

    auto it = std::find_if(CLIENT.begin(), CLIENT.end(),[](const Client& v) { 
        return v.sm_index == 8;
    });
    if (it != CLIENT.end())
    {
      std::cout <<  (*it).name << "\n"; 
    }    
}

【讨论】:

  • 这给了我错误 (const auto& v) auto is not allowed here.
  • @VishalBhatia 这个答案假定 c++11。如果没有,请用您正在使用的 C++ 的特定风格标记您的问题(c++98,microsoft c++,...)
  • @VishalBhatia :如果您的编译器是旧版本,您可以在此处使用 Client 代替 auto 关键字。见已编辑。
  • 更喜欢对已排序的数据使用二进制搜索而不是线性搜索。
【解决方案2】:

如果您的std::vectorsm_index 排序,那么您可以使用二分搜索来查找匹配sm_index 的元素。这将比std::find_if 更快。

C++ 标准库提供了一些用于进行二分搜索的算法。 std::equal_range 可用于查找与sm_index 匹配的多个元素,但如果您只想查找与sm_index 匹配的元素,则可以使用std::lower_bound

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

struct Client {
    std::string name;
    int sm_index;
    int client_id;
    int user_id;

    Client(std::string str, int x,  int y,  int c)
        : name(str), sm_index(x), client_id(y), user_id(c)
    {}

   bool operator<(const Client& a) const { return sm_index < a.sm_index; }
};


int main() {
    std::vector<Client> CLIENT;
    CLIENT.push_back(Client("Rahul",8,1,13));
    CLIENT.push_back(Client("Sahil",12,3,12));
    CLIENT.push_back(Client("Ramesh",1,4,11));
    CLIENT.push_back(Client("Suresh",5,5,10));
    CLIENT.push_back(Client("Ganesh",86,6,9));
    CLIENT.push_back(Client("Gagan",4,7,8));
    std::sort(CLIENT.begin(), CLIENT.end()); 

    Client target("", 5, 0, 0);
    std::vector<Client>::iterator it = std::lower_bound(CLIENT.begin(), CLIENT.end(), target);
    if (it != CLIENT.end()) {
      std::cout <<  it->name << "\n"; 
    }    
}

Live demo.

【讨论】:

    【解决方案3】:

    您可以简单地通过遍历向量并比较属性来做到这一点。我猜你不是在为此寻找优化程序。

    for( auto iter = CLIENT.begin(); iter != CLIENT.end() ; iter++ )
    {
        if( iter->sm_index == 5 ) // compare attribute for your structure
            std::cout << " Found" << std::endl;
    }
    

    已编辑

    这是std::binary_search 的更快方法。

    Client target("",0, 5, 0);
    
    bool found = std::binary_search( CLIENT.begin(), CLIENT.end(), target, []( Client a, Client b ){ return a.client_id < b.client_id; } );
    
    found ? std::cout << "Found" << std::endl : std::cout << "Not found" << std::endl; 
    

    【讨论】:

    • 我的主要目标是快速搜索并遍历向量和 find_if 都做同样的线性搜索,但我正在寻找二进制搜索,因为我已经对我的向量进行了排序。默认 binary_search 函数返回布尔非迭代器。我正在考虑为同样的原因编写我自己的 binary_search 函数。
    • @VishalBhatia std::binary_search 的名字有点糟糕,你可能想要std::lower_boundstd::equal_range。看我的回答。
    猜你喜欢
    • 1970-01-01
    • 2020-05-03
    • 1970-01-01
    • 2020-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多