C++ 从概念上理解容器上的位置访问操作
对于容器上的位置访问操作†的定义,当涉及到C++ 从概念上理解容器上的位置访问操作,c++,data-structures,stl,containers,terminology,C++,Data Structures,Stl,Containers,Terminology,对于容器上的位置访问操作†的定义,当涉及到std::vector、std::deque、std::list和std::forward\u list时,我似乎非常简单。也就是说,访问集合中的第k个元素包括获取存储在集合x中第k个位置的元素 例如,表达式vec[k-1]访问std::vector中的kth,而*std::next(lst.begin(),k-1)对应于它的std::list 然而,当涉及到诸如std::set或std::unordered_set之类的关联容器时,我并不清楚谈论位置访
std::vector
、std::deque
、std::list
和std::forward\u list
时,我似乎非常简单。也就是说,访问集合中的第k个元素包括获取存储在集合x中第k个位置的元素
例如,表达式vec[k-1]
访问std::vector
中的k
th,而*std::next(lst.begin(),k-1)
对应于它的std::list
然而,当涉及到诸如std::set
或std::unordered_set
之类的关联容器时,我并不清楚谈论位置访问操作是否有意义,因为我没有找到一种直接的方法来确定此类容器中任意位置kth的位置
但是,我们仍然可以继续上面所示的std::list
示例,即将迭代器带到关联容器的“第一个”元素(例如,成员函数begin()
)返回的迭代器),然后将迭代器向前移动k-1次(例如,通过std::next()
)
我观察到,容器std::vector
、std::deque
、std::list
和std::forward_list
都是使用线性数据结构实现的,而通常作为二叉树实现的std::set
则不是。因此,这个问题可能与容器实现的底层数据结构的线性有关
有没有办法清楚地定义关联容器的位置访问操作的语义?或者这些访问操作是否不适用于他们
†不要混淆搜索和访问操作。在搜索操作中,您将在集合中查找具有给定键的元素
X这与执行此操作所需的运行时间无关(例如,
std::list
的线性时间,而不是std::vector
的恒定时间),或者是否没有专用的成员函数(例如,std::list
中缺少下标运算符)为了实现这一点。您提到的容器类别之间的最大区别在于,第一个是序列容器,容器的用户明确决定将元素放置在何处,而后者是关联容器,其中,根据元素的某些属性隐式确定生成的顺序,以便能够通过键(std::map
/std::unordered\u map
)/value(std::set
/std::unordered\u set
)高效地访问它们
这并不意味着在这样的容器中通过“位置”进行访问是无用的-因为std::set
保持其元素的排序,所以std::set
中的第k个项目是集合中第k个最小的元素(虽然我确实想不出按位置访问std::unordered_set
的任何目的-哈希通常不会产生任何特别有用的排序1)
除了这个概念上的区别之外,我看不到访问std::list
的第k个元素和对std::set
执行相同操作之间有什么大的操作区别——在这两种情况下,容器都不“本机”支持该操作(例如,容器不支持O(1)随机访问),您必须一次遍历一个元素。即使在引擎罩下,遍历二叉树(如std::set
或std::map
通常使用的二叉树)与在链接列表中(如std::list
中)跟随链接没有多大区别
std::hash
是一种加密散列,它会“清空”原始数据,它可能会有一些微弱的意义,就像“访问随机排列的某个元素”,但是std::hash
只是要求在类型范围内均匀分布,因此例如整数-不是一种特别有趣的排列当您指向列表时,可以定义第k个元素,即指向第k-1元素的指针旁边的指针所指向的元素 您还可以注意到,在数论中,数字也被定义为序列: 1是0旁边的数字,2是1旁边的数字,依此类推 因此,我们可以创建一个结构的同构,该结构由指向容器元素的指针和它们的下一个操作构成,并通过+1操作指向自然数的结构:
p0:=begin() O
|next |increment
p1:=next(begin()) --isomorphic to--> 1:=increment(0)
|next |increment
p2:=next(next(begin())) 2:=increment(increment(0))
. .
. .
这个同构可以用于任何容器,只要它们提供一个开始指针。因此,为了位置的概念,任何STL容器都是等价的。非常有趣的答案。因此,只要容器提供一个到初始元素的前向迭代器,就可以创建同构。