映射,对向量或两个向量..
Map, pair-vector or two vectors...?
我通读了一些帖子和"wiki",但仍然无法决定哪种方法适合我的问题。
我创建了一个名为Sample
的类,它包含一定数量的化合物(假设这是另一个类Nuclide
),具有一定的相对数量(双倍)。
因此,类似(伪):
class Sample {
map<Nuclide, double>;
}
如果我在样本中有核素Ba-133
、Co-60
和Cs-137
,我将不得不在代码中准确地使用这些名称来访问地图中的这些核素。但是,我唯一需要做的就是遍历映射以执行计算(它们是什么核素不感兴趣),因此,我将使用 for- 循环。我想在不注意键名的情况下进行迭代,因此,我需要为地图使用迭代器,对吗?
另一种选择是vector<pair<Nuclide, double> >
class Sample {
vector<pair<Nuclide, double> >;
}
或只是两个独立的向量
Class Sample {
vector<Nuclide>;
vector<double>;
}
而在最后一个选项中,核素与其数量之间的联系将是"元信息",仅由相应载体中的位置给出。
由于我缺乏丰富的经验,我会善意地询问选择哪种方法的建议。我希望快速轻松地迭代所有可用的化合物,同时保持相应键和值的逻辑结构。
PS.:样品中的组合数量可能非常低(1到5)!PPS.:最后一个选项是否可以通过一些const
语句进行修改,以防止更改,从而保持正确的顺序?
如果迭代需要快速,你不希望std::map<...>
:它的迭代是一棵树散步,很快就会变坏。 只有当你对序列有很多突变并且你需要按键排序的序列时,std::map<...>
才是合理的。如果你有突变,但你不在乎顺序std::unordered_map<...>
通常是更好的选择。不过,这两种地图都假设您正在按键查找内容。从你的描述来看,我真的不认为是这样。
std::vector<...>
迭代速度很快。不过,它不适合查找。如果你保持它的顺序,你可以使用std::lower_bound()
来做一个类似std::map<...>
的查找(即,复杂性也是O(log n)
的),但是保持它排序的努力可能会使这个选项过于昂贵。但是,它是将一堆迭代对象放在一起的理想容器。
你想要一个std::vector<std::pair<...>>
还是两个std::vector<...>
取决于你如何访问元素:如果元素的两个部分绑定在一起访问,你需要一个std::vector<std::pair<...>>
,因为它保留一起访问的数据。另一方面,如果您通常只访问两个组件中的一个,则使用两个单独的std::vector<...>
将使迭代更快,因为更多的迭代元素适合缓存行,特别是如果它们像 double
s 一样相当小。
无论如何,我建议不要将外部结构暴露给外部世界,而是提供一个接口,让您稍后更改底层表示。也就是说,为了实现最大的灵活性,您不希望将表示形式烘焙到所有代码中。例如,如果您使用访问器函数对象(BGL 方面的属性映射或 Eric Niebler 的范围提案中的投影)来访问基于迭代器的元素,而不是访问元素,您可以更改内部布局而无需接触任何算法(您需要重新编译代码, 虽然):
// version using std::vector<std::pair<Nuclide, double> >
// - it would just use std::vector<std::pair<Nuclide, double>::iterator as iterator
auto nuclide_projection = [](Sample::key& key) -> Nuclide& {
return key.first;
}
auto value_projecton = [](Sample::key& key) -> double {
return key.second;
}
// version using two std::vectors:
// - it would use an iterator interface to an integer, yielding a std::size_t for *it
struct nuclide_projector {
std::vector<Nuclide>& nuclides;
auto operator()(std::size_t index) -> Nuclide& { return nuclides[index]; }
};
constexpr nuclide_projector nuclide_projection;
struct value_projector {
std::vector<double>& values;
auto operator()(std::size_t index) -> double& { return values[index]; }
};
constexpr value_projector value_projection;
对于一对就地,例如,算法只是在它们上运行并打印它们,如下所示:
template <typename Iterator>
void print(std::ostream& out, Iterator begin, Iterator end) {
for (; begin != end; ++begin) {
out << "nuclide=" << nuclide_projection(*begin) << ' '
<< "value=" << value_projection(*begin) << 'n';
}
}
这两种表示形式完全不同,但访问它们的算法是完全独立的。这样也很容易尝试不同的表示:只需要更改表示和访问它的算法的粘合剂。
- 如何检查两个 std::向量在小于 O(n) 的时间复杂度内是否相等
- 查找两个排序向量中共有的元素
- 如何从文件中读取两个字符串和数字数组,并将它们存储在对象向量中
- 将向量之间的数字放在另一个向量之间<vector>>如果两个数字的差值为 1
- 在类 A 中创建类型为 B 类的向量 - 访问数据 [C++] [成员在两个类中都是私有的]
- 如何根据两个因素组织向量:id 和数量?(C++)
- 在C++中查找两个向量之间最相似的值
- 如何在C++中从两个向量生成所有可能的对?
- 返回两个向量 – 使用引用还是元组?
- 使用 std::vector::swap 方法在C++中交换两个不同的向量是否安全?
- 检查两个向量是否并行的最有效方法
- 有没有办法将两个或多个不同的类链接到一个类中(稍后在向量上使用)?
- 我有一个返回字符串向量的函数.它需要两个字符串,并且返回一个字符串中缺少的字符串
- 如何获得比较两个向量对的子集
- C++将两个不同类型的向量的属性连接到新的向量中
- 如何组合两个整数向量
- 在两个类实例之间共享向量
- 如何在 c++ 中对两个向量进行线性搜索?
- 如何在 c++ 中从两个向量创建 JSON 对象?
- 为什么具有两个元素的发起器语法将一个元素而不是两个元素放入字符串向量中?