4

将缺点用于成对的事物是一种好的风格,还是最好坚持使用列表?

比如问题和答案:

(list
    (cons
        "Favorite color?"
        "red")
    (cons
        "Favorite number?"
        "123")
    (cons
        "Favorite fruit?"
        "avocado"))

我的意思是,有些事情自然而然地成对出现;不需要可以容纳两个以上的东西,所以我觉得缺点是自然的选择。但是,我也觉得我应该坚持一件事(列表)。

什么是更好或更容易接受的风格?

4

3 回答 3

9

你有一个关联列表(alist)。实际上,Alist 条目通常是简单的 conses 而不是列表(尽管这是一个偏好问题:有些人也将列表用于 alist 条目),所以你所拥有的很好。不过,我通常更喜欢使用文字语法:

'(("Favorite color?" . "red")
  ("Favorite number?" . "123")
  ("Favorite fruit?" . "avocado"))

assq列表通常使用符号作为键,因为符号是内嵌的,因此可以使用而不是查找符号列表assoc。以下是它的外观:

'((color . "red")
  (number . "123")
  (fruit . "avocado"))
于 2012-12-07T04:24:02.090 回答
3

这种情况的默认数据结构应该是HASH-TABLE.

缺点对的关联列表也是一种可能的变体,并且在历史上被广泛使用。由于传统和简单,它是一个有效的变体。但是你不应该使用它,当对的数量超过几个时(可能,10 是一个很好的阈值),因为搜索时间是线性的,而在哈希表中它是恒定的。

也可以使用列表来完成此任务,但既丑陋又低效。

于 2012-12-07T06:18:27.350 回答
2

您需要根据具体情况自行决定。没有一个普遍的答案。不同的任务对结构的工作方式不同。考虑以下:

  • 在哈希表中搜索键会更快,然后在 alist 中。
  • 使用 alist 时,使用迭代器并保存其状态更容易(哈希表需要将其所有键导出为数组或列表并具有指向该列表的指针,而只记住指向 alist 的指针,以便能够恢复迭代器的状态并继续迭代。
  • Alist vs list:考虑到所有其他字符都是原子,它们对偶数个元素使用相同数量的 conses。当使用列表与 alists 时,您必须确保没有奇数个元素(并且您可能发现它为时已晚),这很糟糕。
  • 但是还有更多功能,包括内置功能,它们适用于正确的列表,而不适用于 alist。例如nth,如果 alist 命中cdr不是list.
  • 有时某些宏不会像您希望的那样与 alist 一起使用,例如:

(destructuring-bind (a b c d) 
  '((100 . 200) (300 . 400)) 
   (format t "~&~{~s~^,~}" (list a b c d)))

不会像您预期的那样工作。

  • 另一方面,某些程序可能会被“欺骗”去做一些他们不会为正确的列表做的事情。例如,当使用 copy-list 复制 alist 时,只会重新复制cdra的 conses list(取决于具体情况,这可能是所需的结果)。
于 2012-12-07T09:54:00.763 回答