【问题标题】:Return a specific element in a list - LISP返回列表中的特定元素 - LISP
【发布时间】:2019-10-06 07:19:52
【问题描述】:

我正在尝试编写一个名为:get-element (board coords) 的函数,它将一块板和一对表示板位置的坐标作为输入。该对的第一个元素表示列号,第二个元素表示行号(索引从 0 开始)。该函数返回该棋盘位置的内容,可以是 X、O 或 NIL。使用以下测试板状态。

    (defparameter *test-board*
        '((nil nil nil nil nil nil)
          (O   nil nil nil nil nil)
          (X   nil nil nil nil nil)
          (X   X   O   nil nil nil)
          (O   O   X   nil nil nil)
          (nil nil nil nil nil nil)
          (nil nil nil nil nil nil)))

函数应该是这样工作的:

(get-element *test-board* ‘(0 0))
> NIL

我似乎无法理解获得诸如输出之类的过程。到目前为止,我的代码如下(但这是严重错误的!):

  (col(nth 0 coords))
  (row(nth 1 coords)))

任何帮助理解如何检索列表中的特定元素将不胜感激!

【问题讨论】:

    标签: list lisp common-lisp element


    【解决方案1】:

    我不会给你确切的解决方案,但我希望对你自己产生它有用的推理。

    您的数据结构由一个列表组成,其中的每个元素代表棋盘的一行。所以你有一个列表,其中的元素数量等于棋盘的行数。

    这种列表的元素本身就是列表:因此每一行都由一个列表表示,其中每个元素代表棋盘的一个特定单元格(不是一列,一个单元格!)。因此,您的数据结构是列表的列表。

    因此,有人可能会问:在此表示中,板的一列是什么?而答案是:没有实际的数据结构可以称为板的列,简单的列可以抽象地看成:“内部列表中相同位置的所有元素”。

    因此,如果您想从板表示中提取特定单元格,由几个坐标(行号、列号)标识,您必须将此信息“转换”为您的数据结构的特定表示,即而是在列表列表中表示。例如,如果要获取坐标 (3, 5) 处的单元格的内容,即第 3 行第 5 列,则应该这样推理:我可以直接访问第 3 行,因为它是“大”列表的第四个元素,但不是第 5 列,因为没有任何直接对应的元素。

    但是如果我可以访问第3行,例如(nth 3 board),我得到的是与该行的单元格对应的列表,所以不需要获取第5列,我可以取元素5这个列表,我将获得坐标为 (3, 5) 的单元格的内容。因此,获取此列表的第 5 个元素就足够了,例如使用 (nth 5 (nth 3 board))(即,由于 (nth 3 board) 返回该行的单元格列表,因此您从该列表中选择元素 5)。

    我希望这有助于了解如何解决您的问题。

    【讨论】:

      【解决方案2】:
      (defun get-element (list-of-list coord)
        "Return value of field in list-of-list."
        (let ((row (nth (first coord) list-of-list)))
          (nth (second coord) row)))
      
      (defparameter *test-board*
           '((nil nil nil nil nil nil)
             (O   nil nil nil nil nil)
             (X   nil nil nil nil nil)
             (X   X   O   nil nil nil)
             (O   O   X   nil nil nil)
             (nil nil nil nil nil nil)
             (nil nil nil nil nil nil)))
      
      (get-element *test-board* '(0 0)) ;; NIL
      (get-element *test-board* '(1 0)) ;; O
      (get-element *test-board* '(4 2)) ;; X
      

      【讨论】:

        【解决方案3】:

        此函数将从嵌套列表中以数字方式选择任意深度:

        (defun nested-list-coord-select (nested-list coords)
          (loop for coord in coords
                with current = nested-list
                do (setf current (nth coord current))
                finally (return current)))
        
        [1]> (nested-list-coord-select '((a a)) '(0 0))
        A
        [2]> (nested-list-coord-select '((a a)) '(0 1))
        A
        [3]> (nested-list-coord-select '((a b)) '(0 1))
        B
        [4]> (nested-list-coord-select '((a b (c d))) '(0 1))
        B
        [5]> (nested-list-coord-select '((a b (c d))) '(0 2))
        (C D)
        [6]> (nested-list-coord-select '((a b (c d))) '(0 2 0))
        C
        [7]> (nested-list-coord-select '((a b (c d))) '(0 2 1))
        D
        [8]> (nested-list-coord-select '((a b (c d))) '(0 2 1 3))
        
        *** - NTH: D is not a list
        [9]> (nested-list-coord-select nil nil)
        NIL
        [10]> (nested-list-coord-select 42 nil)
        42
        

        如果我们用elt 替换nth(记住要反转参数),那么它会变得更通用。我们可以有一个字符串列表的向量,等等。

        备注:你知道,ANSI Common Lisp 有 N 维数组。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-10-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多