如何在按sm_index排序的结构体vector中查找匹配属性的结构体数据
高效查找已排序Vector中匹配sm_index的Client结构体
既然你的vector<Client>已经按sm_index字段排好序了,那用二分查找绝对是最高效的方案,比挨个遍历快多了!下面给你几种实用的实现方式:
1. 查找第一个匹配的元素
C++标准库的lower_bound函数专门用来在有序序列中找第一个不小于目标值的元素,刚好适配我们的场景。你可以用两种方式实现:
自定义比较函数版本
#include <algorithm> // 必须包含这个头文件 // 自定义比较规则:对比Client的sm_index和目标值 bool compareBySmIndex(const Client& client, int targetSmIndex) { return client.sm_index < targetSmIndex; } // 查找函数,返回匹配元素的指针,未找到则返回nullptr Client* findClientBySmIndex(vector<Client>& clients, int target) { auto it = lower_bound(clients.begin(), clients.end(), target, compareBySmIndex); // 确认找到的元素确实匹配目标sm_index if (it != clients.end() && it->sm_index == target) { return &(*it); } return nullptr; }
Lambda表达式版本(更简洁)
不想单独写比较函数的话,直接用lambda嵌入调用即可:
#include <algorithm> Client* findClientBySmIndex(vector<Client>& clients, int target) { auto it = lower_bound(clients.begin(), clients.end(), target, [](const Client& c, int val) { return c.sm_index < val; }); if (it != clients.end() && it->sm_index == target) { return &(*it); } return nullptr; }
2. 查找所有匹配的元素
如果你的vector里可能存在多个sm_index相同的Client,想要把它们全部捞出来,可以结合lower_bound和upper_bound:
#include <algorithm> #include <vector> vector<Client> findAllClientsBySmIndex(vector<Client>& clients, int target) { vector<Client> matchedClients; // 定位第一个sm_index >= 目标值的位置 auto start = lower_bound(clients.begin(), clients.end(), target, [](const Client& c, int val) { return c.sm_index < val; }); // 定位第一个sm_index > 目标值的位置 auto end = upper_bound(clients.begin(), clients.end(), target, [](int val, const Client& c) { return val < c.sm_index; }); // 把中间所有匹配的元素拷贝到结果集合里 for (auto it = start; it != end; ++it) { matchedClients.push_back(*it); } return matchedClients; }
这里要注意:upper_bound的比较函数参数顺序和lower_bound是反过来的——前者是用目标值和元素比,后者是元素和目标值比,别搞混了!
3. 线性遍历(仅适合小数据量)
如果你的vector元素特别少,线性遍历也能凑合用,但效率远不如二分查找。不过因为vector已经排序,我们可以提前终止循环:
Client* findClientLinear(vector<Client>& clients, int target) { for (auto& client : clients) { if (client.sm_index == target) { return &client; } // 因为已经排序,一旦sm_index超过目标值,后面的肯定更大,直接退出 if (client.sm_index > target) { break; } } return nullptr; }
内容的提问来源于stack exchange,提问作者Vishal Bhatia
相关产品推荐
相关产品推荐

