0

我正在尝试将配对列表作为家庭作业的一部分。

我试着做(在函数中间的某个地方)

(setq list1 (append list1 (cons n1 n2)))

由于某种原因,我不明白,这适用于第一对,但是当我尝试附加第二对时,会弹出此错误:

*** - APPEND:正确的列表不能以 2 结尾

我该如何解决这个问题?

所以,继续这个主题,感谢给出的答案,我能够纠正我的问题。但是一个新的出现了,我认为它与它有关。所以,我有这个功能:

(defun action(state)
(let ((list_actions '())
      (limNumActions (1- (list-length state)))
      (limNumSubActions 0)
      (numActions 0)
      (numSubActions 0))
  (loop for numActions from 0 to limNumActions do
    (setq limNumSubActions (1- (list-length (nth numActions state))))
    (loop for numSubActions from 0 to limNumSubActions do
      (setq list_actions (append list_actions
        (list (cons numActions numSubActions))))
      (print 'list_actions)
      (print list_actions)))))

我将该print函数用作简单的“调试器”。它返回这个:

 LIST_ACTIONS 
 ((0 . 0)) 
 LIST_ACTIONS 
 ((0 . 0) (0 . 1)) 
 LIST_ACTIONS 
 ((0 . 0) (0 . 1) (1 . 0)) 
 LIST_ACTIONS 
 ((0 . 0) (0 . 1) (1 . 0) (1 . 1)) 
 NIL

而这正是我所期待的结果!除了NIL部分...你能理解为什么列表list_actionsNIL最后吗?

4

3 回答 3

1

append需要两个列表,而不是列表和单个元素。在使用它之前,您需要在该对周围放置一个列表append

目前,这对被视为列表的一部分,这使得列表不正确并导致第二次追加失败,因为不正确的列表并没有完全结束追加。

于 2012-11-27T23:08:03.257 回答
1

代码可以更简洁地表达如下:

(defun action (state)
  (let ((list-actions '()))
    (loop for i from 0 for state-i in state do
      (loop for j from 0 below (length state-i) do
        (setf list-actions (append list-actions (list (cons i j))))
        (print 'list-actions)
        (print list-actions)))
    list-actions))

如果只需要结果,它可以更短(并且成本更低,因为它不使用昂贵的append功能),

(defun action (state)
  (loop for i from 0 for state-i in state append
    (loop for j below (length state-i) collect (cons i j))))
于 2012-11-28T03:59:47.543 回答
0

我试图稍微改进您的示例 + 编写一个使用不同但 IMO 更惯用的解决问题方法的版本:

;; Your original version, but cleaned up a bit
(defun action (state)
  (loop with list-actions = nil
     with lim-num-actions = (1- (list-length state))
     with lim-num-sub-actions = 0
     for num-actions from 0 to lim-num-actions
     do (setq lim-num-sub-actions (1- (list-length (nth num-actions state))))
       (loop for num-sub-actions from 0 to lim-num-sub-actions
          do (push (cons num-actions num-sub-actions) list-actions)
            (format t "~&~s ~s" 'list-actions list-actions))
     finally (return list-actions)))

;; A more traditional approach (if you want to use iteration)
(defun action (state)
  (reverse 
   (loop for i in state
      for j from 0
      collect (cons j 0))))

;; Using a nice library to do iteration
(ql:quickload "iterate")
;; Note, you could do (in-package :iterate)
;; to lose `iterate:' prefix to make it even shorter
(defun action (state)
  (iterate:iter
    (iterate:for i #:on state)
    (iterate:for j #:from 0)
    (iterate:accumulate (cons j 0) #:by #'cons)))

;; Just another way to do this, using `reduce'
(reduce #'(lambda (a b)
            (declare (ignore b))
            (cons (cons (1+ (caar a)) 0) a))
        (cdr (mapcar #'list '(1 2 3 4 5)))
        :initial-value '((0 . 0)))

(action (mapcar #'list '(1 2 3 4 5)))
于 2012-11-28T01:15:13.000 回答