Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.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
Clojure 作为一个数据容器,vector和list的主要区别是什么_Clojure - Fatal编程技术网

Clojure 作为一个数据容器,vector和list的主要区别是什么

Clojure 作为一个数据容器,vector和list的主要区别是什么,clojure,Clojure,假设我们需要一个数字列表,有两种定义: (def vector1 [1 2 3]) (def list2 '(1 2 3)) 那么主要的区别是什么呢?的[1 2 3]是a,而'(1 2 3)是a。这两种数据结构具有不同的性能特征 向量提供对其元素的快速、索引的随机访问(v34)在O(1)时间内,在索引34处返回向量v的元素。另一方面,修改向量通常更昂贵 列表很容易在开头和/或结尾进行修改(取决于实现),但提供了对元素的线性访问:(第n个(列表1、2、3、4、5)3)需要对列表进行顺序扫描 有关

假设我们需要一个数字列表,有两种定义:

(def vector1 [1 2 3])
(def list2 '(1 2 3))

那么主要的区别是什么呢?

[1 2 3]
是a,而
'(1 2 3)
是a。这两种数据结构具有不同的性能特征

向量提供对其元素的快速、索引的随机访问
(v34)
O(1)
时间内,在索引
34
处返回向量
v
的元素。另一方面,修改向量通常更昂贵

列表很容易在开头和/或结尾进行修改(取决于实现),但提供了对元素的线性访问:
(第n个(列表1、2、3、4、5)3)
需要对列表进行顺序扫描

有关性能权衡的更多信息,您可以在谷歌上搜索“vector vs.list performance”或类似内容

[后续行动]

好的,让我们进入更多的细节。首先,向量和列表是不特定于Clojure的概念。与映射、队列等一起,它们是数据集合的抽象类型。根据这些抽象定义了对数据进行操作的算法。向量和列表是由我在上面简要描述的行为定义的(即,如果某个东西有大小,那么它就是一个向量,你可以访问它的元素,并在固定时间内建立索引等)

Clojure和其他任何语言一样,在提供以这种方式命名的数据结构时,希望满足这些期望。如果您查看,您将看到对方法的
arrayFor调用,该方法的复杂性为O(log32N),在Java数组中的查找为O(1)

为什么我们可以说
(v34)
实际上是O(1)?因为Java
int
的log32的最大值约为7。这意味着对向量的随机访问实际上是恒定时间


总之,
向量
列表
之间的主要区别实际上是性能特征。此外,正如Jeremy Heiler所指出的,Clojure在行为上存在逻辑上的差异,也就是说,随着集合的增加,向量评估时间不是O(1),而是log32N

向量(IPersistentVector)
向量是由连续整数索引的值的集合。向量支持通过log32N跃点中的索引访问项。计数为O(1)。conj将该项放在向量的末尾。向量还支持rseq,它以相反的顺序返回项目。向量实现IFn,用于一个参数的invoke(),它们假定该参数是一个索引,并在自身中查找,就好像在第n步一样,即向量是其索引的函数。

列表和向量之间有两个主要区别

  • 列表逻辑上在头部增长,而向量逻辑上在尾部增长。在使用
    conj
    功能时,您可以看到这一点。它将根据提供给它的集合类型来增加集合。虽然您可以在任何一方增加集合,但这样做是非常有效的

  • 为了检索列表中的第n项,需要从头部遍历该列表。另一方面,向量不被遍历并返回O(1)中的第n项。(这实际上是O(log32n),但这是由于集合是如何作为持久集合实现的。)

    • 向量保存内存相邻区域中的所有数据项,使 整个向量的转移以及项目的插入或删除 与列表相比,价格昂贵

    • 列表保存的项目是内存中不相交的区域,进行数据传输 整个列表很昂贵,但插入和删除单个项目 相对便宜

    • 经典向量的大小也是固定的,并且限制为N项,而 列表可以动态地增长和收缩

    • 向量还提供对元素项的索引访问。清单上没有。 经典向量的前身是数组
    • 向量的现代实现通常旨在提供类似的 特性,但底层数据结构实际上可能是 列表或散列,这些向量通常支持动态 重新调整尺寸

    你的意思是
    log2N
    ?。但是根据clojure的备忘单,
    (我的vec idx)→ (第n个my vec idx)
    ,将
    (my vec idx)
    转换为第n个
    调用。而且,从第N个
    的文档中,访问元素是
    O(N)
    。@xiaowl,请仔细阅读文档。O(n)时间是指序列的第n项,由于抽象的要求,必须遍历该项。对于向量,在所有密集用途中,它是O(1)。嗨,Pawel,似乎复杂性不是
    O(1)
    。原因
    (my vec idx)
    被翻译成
    (nth my vec idx)
    @xiaowl
    nth
    是一个用于向量和列表的函数,它提供了对向量的快速访问。仅供参考,我在Clojure的上下文中看到的术语实际上是恒定时间,而不是事实上的恒定时间。