从概念上理解容器上的位置访问操作
Posted
技术标签:
【中文标题】从概念上理解容器上的位置访问操作【英文标题】:Conceptually understanding positional access operations on containers 【发布时间】:2019-06-13 23:48:18 【问题描述】:位置访问操作†在容器上的定义可能看起来像std::vector
,@987654322,对我来说似乎很简单@、std::list
和 std::forward_list
。也就是说,访问集合中的第kth元素包括获取存储在位置kth的元素在集合中X。
例如,表达式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
都是使用 linear 数据结构实现的,而 std::set
通常实现为二叉树,不是。所以,这个问题可能与容器实现的底层数据结构的线性有关。
有没有什么方法可以清楚地定义关联容器的位置访问操作的语义?或者这样的访问操作对他们不适用吗?
† 不要混淆 search 和 access 操作。在搜索操作中,您正在寻找集合中具有给定键的元素。
X 这与执行此操作所需的运行时间无关(例如,std::list
的线性时间而不是std::vector
的恒定时间)或是否没有专用的成员函数(例如,std::list
中缺少下标运算符)来实现这一点。
【问题讨论】:
【参考方案1】:您提到的容器类别之间的最大区别在于第一个是 sequence 容器,其中容器的用户明确确定放置元素的位置,而后者是 关联容器,其中生成的顺序由元素的某些属性隐式确定,以便可以通过键 (std::map
/std::unordered_map
)/值 (std::set
/std::unordered_set
) 有效地访问它们.
这并不意味着在此类容器中通过“位置”进行访问是没有用的 - 因为std::set
保持其元素排序,std::set
中的第 kth 项是 kth 集合中的最小元素(虽然我确实想不出按位置访问std::unordered_set
的任何目的 - 散列通常不会产生任何特别有用的排序1)。
除了这个概念上的区别之外,我认为访问std::list
的第 kth 元素和在 std::set
上执行相同操作之间没有任何大的操作差异 - 在这两种情况下,操作不是容器“本机”支持的(例如,容器不支持 O(1) 随机访问),并且您必须一次遍历一个元素。即使在底层,像std::set
或std::map
通常使用的二叉树也与跟踪链表中的链接(例如std::list
)没有太大区别。
-
如果
std::hash
是一个加密散列,它“白化”了原始数据,它可能是“访问随机排列的某些元素”,但std::hash
只需要很好地分布在类型范围,例如整数 are often hashed as themselves - 不是一个特别有趣的排列。
【讨论】:
【参考方案2】:当你指向一个列表时,可以定义第 kth 元素,该元素由指向第 kth-1 的指针旁边的指针指向的元素。 sup> 元素。
您还可以注意到,在数论中,数字也被定义为序列: 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 容器都是等价的。
【讨论】:
非常有趣的答案。因此,只要容器为初始元素提供前向迭代器,就可以创建同构。以上是关于从概念上理解容器上的位置访问操作的主要内容,如果未能解决你的问题,请参考以下文章