几个相同大小的向量.给定其中一个向量中的元素,快速访问其他向量中的相应元素

A few vectors of same size. Given element in one of the vectors, fast access to corresponding elements in the other vectors

本文关键字:向量 元素 其他 访问 一个 几个      更新时间:2023-10-16
std::vector<std::string> vec1, vec2, vec3, vec4;
//populate all vectors, all have the same size
//vec1 has different values

现在给定 vec1 中的一些"键",例如"foo",如何快速从其他向量中获取相应的字符串?

我将不得不多次执行此操作,在 vec1 中使用不同的键,因此此操作必须快速。

我是否应该创建一个映射,将 vec1 中的元素映射到索引值 (0,1,2,3,4...(?

如何在C++最好地做到这一点?

取决于你所说的"快速"是什么意思。

如果您关心按值检索的复杂性,我建议您考虑使用关联容器,例如 std::unordered_set(常量查找和插入/删除时间(,或std::setstd::multiset(对数查找和插入/删除时间,第二个允许重复(而不是vector

但是,必须说vector分配一个连续的内存区域来存储它们的元素,因此线性访问将导致高缓存命中率:因此,即使复杂性更差,访问通常仍然是"快速"的,您可以使用常规的 STL 算法(如 std::findstd::find_if()(来查找与给定值匹配或满足给定谓词的元素。

通常,数据的位置性可以弥补更糟糕的复杂性。这里的关键是始终进行重复测量,以确定为您提供最佳性能的解决方案。

也就是说,最佳解决方案可能取决于您的整体工作负载:您是否对向量进行逐个元素的迭代?您需要多久按位置检索一次元素?如果这些操作不是频繁操作,则可能不需要向量。此外,这些载体多久更新一次?您需要多久按值查找一次这些向量中的元素?你的问题对此没有说太多。

如果内存开销对您来说不是问题,您当然可以考虑构建一个单独的映射作为索引,并维护冗余结构。但是,如果您的vector将频繁更新插入和删除,则确保索引和vector的一致性可能会变得麻烦。

听起来你真正想要的是一个std::unordered_map<std::string, std::tuple<std::string, std::string, std::string>>。这样可以避免维护std::vector长度必须相同的不变性。它还将为您提供其他字符串的恒定时间查找。例如

typedef std::tuple<std::string, std::string, std::string> value_type;
std::unordered_map<std::string, value_type> map;
// Populate the map
map["foo"] = std::make_tuple("first", "second", "third");
// ...
std::get<0>(map["foo"]); // Get the first string that "foo" maps to

如果你真的不想改变设计,从使用四个std::vector,那么你应该使用 std::findstd::distance 在第一个std::vector中找到 "foo" 的索引,然后在其他索引上使用该索引:

auto key_it = std::find(std::begin(vec1), std::end(vec1), "foo");
int index = std::distance(std::begin(vec1), key_it);
std::string s2 = vec2[index];
std::string s3 = vec3[index];
std::string s4 = vec4[index];