【问题标题】:What is the actual definition of an array? [duplicate]数组的实际定义是什么? [复制]
【发布时间】:2010-12-06 21:55:04
【问题描述】:

可能重复:
Arrays, What’s the point?

我之前曾尝试在What is the difference between an array and a list? 中问过这个问题,但我的问题在得到结论性答案之前就被关闭了 (more about that)。

我试图理解计算机科学中“数组”一词的真正含义。我正在尝试根据本网站的精神得出一个没有讨论的答案。我要问的是语言不可知论,但您可以利用您对数组在您使用的各种语言中的作用/作用的了解。

思考这个问题的方式:

  • 假设您正在设计一种新的编程语言并决定在其中实现数组;这意味着他们做什么?这些东西的属性和能力是什么。如果取决于语言类型,那又如何?
  • 是什么让数组成为数组?
  • 什么时候数组不是数组?例如,什么时候是列表、向量、表格、地图或集合?

对于什么是数组可能没有一个精确的定义,如果是这样,那么是否有任何标准或接近标准的假设或数组是什么?至少有公共区域吗?也许有几个定义,如果是这样的话,我正在寻找每个定义中最精确的。

语言示例:

(如果我在这些方面有误,请纠正我)。

  • C 数组是单一类型的连续内存块,可以使用指针算术遍历或在特定偏移点访问。它们具有固定的大小。
  • JavaScript、Ruby 和 PHP 中的数组具有可变大小,可以存储任何类型的对象/标量,它们也可以增长或从中删除元素。
  • PHP 数组有两种类型:数值型和关联型。关联数组具有使用字符串键存储和检索的元素。数值数组具有使用整数存储和检索的元素。有趣的是,如果你有:$eg = array('a', 'b', 'c')unset($eg[1]),你仍然使用 $eg[2] 检索 'c',只是现在 $eg[1] 是未定义的。 (您可以调用array_values() 重新索引数组)。您还可以混合使用字符串和整数键。

在这个阶段,有点怀疑 C 数组是这里唯一真正的数组,严格来说,一个数组要成为一个数组,它必须具有我在第一个要点中提到的所有特征。如果是这样的话——这也是我希望确认或拒绝的怀疑——JS 和 Ruby 中的数组实际上是向量,而 PHP 数组可能是某种表。

最后说明:我已经创建了这个社区 wiki,因此如果需要对答案进行多次编辑以代替 cmets,请继续执行此操作。在这里达成共识。

【问题讨论】:

  • PHP 数组实际上是其他语言中的列表和数组的组合。所以这里最好不要提。 - 可能会引起混乱。
  • 人类语言几乎从来都不是正式语言。当你试图找到“实际”或“真实”的定义时,你是在找错树。空无一人。我们所拥有的只是传统和共识,而共识经常在边缘破裂。就 C、Javascript、Ruby 和 PHP 是形式语言而言,它们可以定义数组在语言上下文中的含义,但这些定义没有义务集中在一个通用模型上,它们都是 '语言上下文中的“真实”和“真实”。
  • @Nicholas Knight - 只要你能得到足够多的人同意你的观点……共识是这里的关键。
  • @Nicholas:正确。定义仅在特定概念框架的上下文中是“正确的”或“错误的”。如果您选择以一种“可以”的奇怪方式定义您的术语,只要您在逻辑上保持一致即可。只是不要指望其他人会理解你......甚至懒得去尝试:-)
  • 关闭这些东西到底有什么意义?你只是喜欢破坏人们的日子。那个“重复”是一个完全不同的问题!

标签: arrays terminology definitions


【解决方案1】:

数组是按整数索引的数据项的有序集合。不可能确定更多。投票给这个答案,你认为这是这个问题唯一合理的结果。

【讨论】:

  • 这在技术上是正确的,但它没有得到我的投票,因为大多数人会有不同的心理模型。不幸的是,有许多(相互冲突的)心智模型。没有定义会得到我的投票,因为我认为不可能达成共识。从根本上说,定义是关于共识/共同理解,而不是流行度。
  • 我们可以确定一个数组是一个有序的集合,特别是在数学意义上它是由整数索引的。
  • 嗯,但是在 PHP 中,数组可以有一个字符串索引。所以我猜共识在这个属性之前就停止了。
【解决方案2】:

一个数组:

  1. 是元素的有限集合
  2. 元素是有序的,这是它们唯一的结构
  3. 相同类型的元素
  4. 支持高效随机访问
  5. 不期望有效插入
  6. 可能支持也可能不支持追加

(1) 将数组与迭代器或生成器等区别开来。 (2) 区分数组和集合。 (3) 将数组与你得到一个 int 和一个字符串的元组之类的东西区分开来。 (4) 将数组与其他类型的列表区分开来。也许这并不总是正确的,但程序员的期望是随机访问是恒定的时间。 (5) 和 (6) 只是用来拒绝额外的要求。

【讨论】:

    【解决方案3】:

    如果您忽略编程语言如何建模数组和列表,而忽略抽象的实现细节(以及随之而来的性能特征),那么数组和列表的概念就无法区分。

    如果您介绍实现细节(仍然独立于编程语言),您可以比较链表、数组列表、常规数组、稀疏数组等数据结构。但是你不再比较数组和列表本身。

    在我看来,您只能在编程语言的上下文中谈论数组和列表之间的区别。当然,您随后会谈论该语言支持的数组和列表。你不能泛化到任何其他语言。

    总之,我认为这个问题是建立在一个错误的前提之上的,并且没有有用的答案。

    编辑:回应 Ollie 的 cmets:

    我并不是说使用“数组”和“列表”这两个词没有用。我要说的是这些词没有也不能有精确和不同的定义……除非在特定编程语言的上下文中。虽然您希望这两个词具有不同的含义,但事实并非如此。看看这些词的实际使用方式。此外,试图将一套新的定义强加给世界注定要失败。

    我关于实现的观点是,当我们比较和对比数组和列表的不同实现时,我们就是这样做的。我并不是说这不是一件有用的事情。我要说的是,当我们比较和对比各种实现时,我们不应该完全挂断我们是否称它们为数组或列表或其他任何东西。相反,我们应该使用我们可以同意的条款……或者根本不使用条款。

    对我来说,“数组”的意思是“可以有效索引的事物的有序集合”,“列表”的意思是“可以有效索引的事物的有序集合”。但是有一些数组和列表的例子都与趋势背道而驰。例如一方面是 PHP 数组,另一方面是 Java ArrayLists。因此,如果我想准确地说……在与语言无关的上下文中,我必须谈论“类 C 数组”或“链表”或其他一些术语,以明确我真正的意思是什么数据结构。如果我想清楚的话,术语“数组”和“列表”是没有用的。

    【讨论】:

    • 没有答案对我来说是一个合法且有用的答案。但我不同意你之前说的很多话,所以我对你投了反对票,对不起。
    • @Ollie:具体来说你不同意什么......并证明。
    • 这些词“数组”和“列表”存在——或者应该存在——来表示不同数据结构的特征和限制。当您删除实现细节时,您说数组和列表是相同的是正确的,但我认为这没有抓住重点。这是我关心的实现细节。毕竟,拥有不同数据结构的动机几乎完全是为了性能,否则我们只会对所有内容使用哈希表。
    • @Ollie - 实现细节与语言无关。你被语义迷住了。
    • 我不同意。实现细节与语言无关。如果某件事在一个结构中花费恒定时间而在另一个结构中花费线性时间,那么语法是什么样的并不重要。这是一种简化,但并不过分。
    【解决方案4】:

    我认为 real 数组将值存储在 连续 内存中。其他任何东西都只称为数组,因为它可以像数组一样使用,但它们并不是真正的(PHP 中的“数组”肯定不是 实际 数组(非关联))。向量等是数组的扩展,增加了额外的功能。

    【讨论】:

      【解决方案5】:

      数组|əˈrā|

      名词

      1 对特定类型事物的令人印象深刻的展示或范围:关于该主题有大量文献 | 一系列令人眼花缭乱的选择

      2 一个有序的排列,特别是

      • 部队的安排。
        1. 数学:数量或符号在行和列中的排列;一个矩阵。
        2. 计算:一组有序的相关元素。
        3. 法律:指定陪审员名单。

      3 诗意的/文学的精致或美丽的衣服:他衣冠楚楚。 动词

      1. [ 反式。 ] (usu. be arrayed) 以特定的方式展示或安排(东西): 摆在桌子上的是自助餐 |对他不利的力量。
      2. [ 反式。 ](usu. be arrayed in)给某人穿上(指定的衣服):他们穿着匈牙利民族服饰。
      3. [ 反式。 ] 法律专家(陪审团)。 起源 中古英语(在 [preparedness] 和 [place in readiness] 的意义上):源自古法语 arei(名词),areer(动词),基于拉丁语 ad- 'toward' + 一个日耳曼语基础,意思是 'prepare'。李>

      【讨论】:

      • 嘿,这很有趣,而且不知何故几乎......完美......
      • 我有同一个字典!尽管如此,还是有道理的。
      • 字典的实际定义是什么?
      • @Tom:字典有一个很好理解的精确定义。数组没有。这就是为什么这个问题存在于数组而不是字典的原因。
      • 我认为这不值得这么多赞成...
      【解决方案6】:

      数组是一个容器,它所保存的对象除了顺序之外没有任何关系;对象抽象地存储在一个连续的空间中(高级,当然低级也可能是连续的),因此您可以通过 slot[x,y,z...] 访问它们。 例如,对于每个数组[2,3,5,7,1],您可以使用 slot[2](在某些语言中为 slot[3])获得 5。

      对于一个列表,也是一个容器,它所持有的每个对象(嗯,每个对象持有者,例如插槽或节点)都有指示符“指向”其他对象,并且这个是主要关系;一般来说,无论是高层还是低层,空间都是不连续的,但可能是连续的;所以不推荐通过 slot[x,y,z...] 访问。 例如,根据 |-2-3-5-7-1-|,您需要从第一个对象移动到第三个对象才能获得 5。

      【讨论】:

        【解决方案7】:

        来自FOLDOC

        数组

        1. programming> 同类型数据项的集合 通过它们的索引(或“下标”)来区分。号码 数组可以具有的维度取决于语言,但 通常是无限的。

        数组是一种aggregate 数据类型。一个 普通变量(“scalar”)可以被认为是 零维数组。一维数组也是已知的 作为“vector”。

        对数组元素的引用写成类似 A[i,j,k] 其中 A 是数组名称,i、j 和 k 是 指数。 C 语言的特殊之处在于每个索引都是 写在单独的括号中,例如A[i][j][k]。这表示 事实上,在 C 中,N 维数组实际上是 向量,每个元素都是一个 N-1 维数组。

        数组的元素通常是连续存储的。 语言在最左边或最右边的索引方面有所不同 变化最快,即是否存储每一行 连续或每列(对于二维数组)。

        数组适用于存储必须访问的数据 以不可预测的顺序,与lists 相比,它们是 最好按顺序访问。数组索引是 integers,通常是natural numbers,而 associative array 由字符串标识。

        2. architecture> A processor array,不要与 一个array processor

        另请注意,在某些语言中,当他们说“数组”时,实际上是指“associative array”:

        关联数组

        programming>(或“哈希”、“地图”、“字典”)一个array indices 不仅是 integers,而且可能是 任意字符串。

        awk 及其后代(例如Perl)具有关联 使用hash coding 实现更快的数组 抬头。

        【讨论】:

        • 我可以向您展示引用定义中使用的数组和列表示例的反例。例如,稀疏数组不是连续存储的,Java ArrayLists(或等效的)是为随机访问而设计的。除此之外,还有数组/列表实现的属性,而不是底层概念。
        • 虽然稀疏数组并不常见。
        • Stephen:它确实说“数组的元素通常连续存储”。 Java的List接口说“[位置]操作可能会在某些实现的索引值成比例的时间内执行...... [因此]迭代列表中的元素通常比通过它索引更可取”这几乎就是上面所说的. List 的特定实现(其名称中包含“array”!)具有 O(1) 随机访问这一事实并不能使“list”通常意味着按顺序访问的东西的说法无效。
        【解决方案8】:

        它是或者应该是关于抽象

        其实里面隐藏了一个好问题,一个非常好的问题,它引发了我长期以来对语言的不满。

        而且情况越来越糟,而不是更好。

        好的:Fortran 做得对,但我最喜欢的语言(如 Ruby)仍然出错:它们对函数调用、数组和属性使用不同的语法。这到底有多抽象?在 fortran 中,function(1)array(1) 具有相同的语法,因此您可以在不更改程序的情况下将其中一个更改为另一个。 (我知道,不是为了作业,而在 Fortran 的情况下,这可能是愚蠢的穿孔卡片字符集的意外,而不是任何故意的。)

        关键是,我真的不确定x.yx[y]x(y) 应该有不同的语法。将特定抽象附加到特定语法有什么好处?为致力于重构转换的 IDE 程序员创造更多工作?

        说了这么多,定义array 很容易。在它的第一种正常形式中,它是内存中的连续元素序列,通过数字偏移量并使用特定于语言的语法进行访问。在更高范式中,它是响应典型数字消息的对象的属性。

        【讨论】:

        • 我认为你的观点在我这里被忽略了。这是一个耻辱,因为它听起来很有趣。你认为隐藏的好问题是什么?另外,我不完全了解您所说的有关语法的内容(我确定确实如此!但​​我现在没有看到)。您对数组的定义已注明,感谢您的回答。
        • 好吧,我主张使用统一的语法向对象发送消息,以便将使用与实现分离,并使对象在不同意义上具有多态性。这与数组的定义有关,它最初是向量和矩阵抽象到左值的简单映射,正如 C 所称的那样,但现在 [] 运算符有时可以重新定义(可能实现稀疏矩阵或其他)所以现在我看不出调用函数、访问属性或索引数组之间的区别。它们都是关于向对象发送消息。
        • +1 因为你让我重新思考自己的“理想语言”设计。
        • 我想指出,在 Clojure 中,Vectors 实际上是其索引的函数,而 Maps 是其键的函数。
        猜你喜欢
        • 2019-11-15
        • 2022-09-22
        • 1970-01-01
        • 1970-01-01
        • 2021-09-17
        • 2013-03-24
        • 2019-05-03
        • 1970-01-01
        • 2019-12-18
        相关资源
        最近更新 更多