繁体   English   中英

C++ 在向量中查找<int, pair>

[英]C++ Find in a vector of <int, pair>

所以以前我只需要查找 1 个密钥,所以我可以使用地图:

std::map <int, double> freqMap;

但现在我需要查找 2 个不同的键。 我正在考虑使用带有 std::pair 的向量,即:

std::vector <int, std::pair<int, double>> freqMap;

最终我需要查找两个键才能找到正确的值。 有没有更好的方法来做到这一点,或者这是否足够有效(将有大约 3k 个条目)。 另外,不确定如何使用第二个键(std::pair 中的第一个键)进行搜索。 是否可以根据第一个键找到该对? 基本上我可以通过以下方式访问第一个密钥:

freqMap[key1]

但不确定如何迭代并找到该对中的第二个键。

编辑:好的,添加用例进行澄清:

我需要根据 2 个键、一个多路复用器选择和一个频率选择查找一个 val。 原始数据如下所示:

Mux, Freq, Val
0, 1000, 1.1
0, 2000, 2.7
0, 10e9, 1,7
1, 1000, 2.2
1, 2500, 0.8
6, 2000, 2.2

“哪个更快”的总体答案通常是“您必须对其进行基准测试”。

但除此之外,您还有多种选择。 std::map在纸上比其他数据结构更有效,但在实践中不一定。 如果您确实处于性能至关重要的情况(即避免过早优化),请尝试不同的方法,如下所示,并测量您获得的性能(内存和 CPU 方面)。


与其使用std::map ,不如考虑将您的数据放入struct ,给它适当的名称并将所有值存储在一个简单的std::vector 如果您很少修改数据,您可以通过根据您通常用来查找条目的键对向量进行排序,从而以额外的插入成本为代价来优化检索成本 这将允许你做的二进制搜索,它可以是速度远远超过线性搜索

然而,由于缓存局部性分支预测,线性搜索在std::vector上可能出奇地快。 在处理地图、unordered_map 或(二进制搜索)排序向量时,您可能会丢失这两者。 因此,尽管 O(n) 听起来比 map 的 O(log n) 甚至 unordered_map 的 O(1) 更可怕,但在正确的条件下它仍然可以更快。

特别是如果你发现你没有一个可辨别的索引成员可以用来对你的条目进行排序,你将不得不在连续内存(即向量)中坚持线性搜索投资于双索引数据结构(实际上类似于到两个地图或两个 unordered_maps)。 拥有两个索引通常会阻止您使用单个 map/unordered_map。

如果你可以更紧密地打包你的数据(即你需要一个int还是一个std::uint8_t完成这项工作?,你需要一个double吗?等等)你将放大缓存局部性,并且只有 3k 个条目,你有很好的机会一个未排序的向量来表现最好。 尽管对std::size_t操作本身通常比在较小的类型上更快,但在连续内存上迭代通常会抵消这种影响。


结论:尝试一个未排序的向量、一个排序的向量(+二元搜索)、一个映射和一个 unordered_map。 进行适当的基准测试(多次重复)并选择最快的。 如果它没有区别,请选择最容易理解的那个。


编辑:鉴于您的示例数据,听起来第一个键的域非常小。 据我所知,“Mux”似乎仅限于少数彼此靠近的不同值,在这种情况下,您可以考虑使用std::array作为主要索引结构并具有合适的查找结构作为你的第二个。 例如:

std::array<std::vector<std::pair<std::uint64_t,double>>,10>
std::array<std::unordered_map<std::uint64_t,double>,10>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM