Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从概念上理解容器上的位置访问操作_C++_Data Structures_Stl_Containers_Terminology - Fatal编程技术网

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容器都是等价的。

    非常有趣的答案。因此,只要容器提供一个到初始元素的前向迭代器,就可以创建同构。