Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/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
Common lisp Lisp-循环列表并替换值_Common Lisp - Fatal编程技术网

Common lisp Lisp-循环列表并替换值

Common lisp Lisp-循环列表并替换值,common-lisp,Common Lisp,在这个问题中,我有三个(结构相同的)列表。其中两个包含所有数字,另一个填充有nil。我试图用两个列表中的对应值相加来替换空列表中的对应值。到目前为止,我使用的是一个循环,并使用setf替换该值 (定义添加两个列表(列表1列表2列表3) (列表1中的循环 对于清单2中的b 对于清单3中的c,请执行以下操作 (setf c(ab)) 问题是这个功能没有破坏性。如何使此函数具有破坏性 好的,我知道我可以使用apply来做这件事,但是为了将来或相切的目的,有没有办法使用循环来做同样的事情 我决定采

在这个问题中,我有三个(结构相同的)列表。其中两个包含所有数字,另一个填充有
nil
。我试图用两个列表中的对应值相加来替换空列表中的对应值。到目前为止,我使用的是一个循环,并使用
setf
替换该值

(定义添加两个列表(列表1列表2列表3)
(列表1中的循环
对于清单2中的b
对于清单3中的c,请执行以下操作
(setf c(ab))
问题是这个功能没有破坏性。如何使此函数具有破坏性


好的,我知道我可以使用
apply
来做这件事,但是为了将来或相切的目的,有没有办法使用循环来做同样的事情


我决定采用倒数第二种解决办法;使用列表长度横穿列表。

这里有一个方法:

(defun add-two-lists (list1 list2 list3)
   (loop for a in list1
        for b in list2
        for c on list3 do
        (rplaca c (+ a b)))
附录

以下是使用映射而不是循环的另一种方法:

(defun add-two-lists (list1 list2 list3)
  (mapl #'(lambda (cl al bl) (rplaca cl (+ (car al) (car bl))))
    list3 list1 list2))

还有一种不用循环就可以做同样事情的方法(尽管在概念上很相似)

编辑

(defun add-two-lists (a b c &optional (d c))
  (if a
    (add-two-lists
     (cdr a) (cdr b)
     (cdr (rplaca c (+ (car a) (car b)))) d) d))

(time
 (dotimes (i 1e6)
   (add-two-lists '(1 2 3 4 5)
          '(1 2 3 4 5)
          '(nil nil nil nil nil))))

;; Evaluation took:
;;   0.077 seconds of real time
;;   0.076004 seconds of total run time (0.076004 user, 0.000000 system)
;;   98.70% CPU
;;   214,723,476 processor cycles
;;   0 bytes consed

(defun add-two-lists-1 (list1 list2 list3)
  (loop for a in list1
     for b in list2
     for c on list3 do
       (rplaca c (+ a b))))

(time
 (dotimes (i 1e6)
   (add-two-lists-1 '(1 2 3 4 5)
          '(1 2 3 4 5)
          '(nil nil nil nil nil))))

;; Evaluation took:
;;   0.060 seconds of real time
;;   0.060004 seconds of total run time (0.060004 user, 0.000000 system)
;;   100.00% CPU
;;   169,395,444 processor cycles
;;   0 bytes consed
编辑2

但是请注意优化的版本行为。同样,可能是YMMV,但这是我在64位Debian和SBCL上得到的

(defun add-two-lists (a b c &optional (d c))
  (declare (optimize (speed 3) (safety 0)))
  (declare (type list a b c d))
  (if a
    (add-two-lists
     (cdr a) (cdr b)
     (cdr (rplaca
       c 
       (the fixnum
         (+ (the fixnum (car a))
        (the fixnum (car b)))))) d) d))

(time
 (dotimes (i 1e6)
   (add-two-lists '(1 2 3 4 5)
          '(1 2 3 4 5)
          '(nil nil nil nil nil))))

;; Evaluation took:
;;   0.041 seconds of real time
;;   0.040002 seconds of total run time (0.040002 user, 0.000000 system)
;;   97.56% CPU
;;   114,176,175 processor cycles
;;   0 bytes consed

(defun add-two-lists-1 (list1 list2 list3)
  (declare (optimize (speed 3) (safety 0)))
  (loop for a fixnum in list1
     for b fixnum in list2
     for c cons on list3 do
       (rplaca c (the fixnum (+ a b)))))

(time
 (dotimes (i 1e6)
   (add-two-lists-1 '(1 2 3 4 5)
          '(1 2 3 4 5)
          '(nil nil nil nil nil))))

;; Evaluation took:
;;   0.040 seconds of real time
;;   0.040003 seconds of total run time (0.040003 user, 0.000000 system)
;;   100.00% CPU
;;   112,032,123 processor cycles
;;   0 bytes consed

Common Lisp为此提供了一个函数:。

我最喜欢的制作破坏性函数的方法:我用宏伟的愿景填充它,说服它释放愤怒,让仇恨流过它。它通常是有效的,除非有一个子函数把它带回到光明的一面。使用NTH是最糟糕的方法。@SomeKittens Awesome,man:Dis
rplaca
common lisp的一部分?它与setf有何不同?是的,rplaca是公共Lisp的一部分(setf在修改的地方是cons的car时使用rplaca):--你可以说(setf(car c)…)而不是(rplaca c…),我认为这个递归解决方案是最后的选择。在这种情况下,我担心速度,所以我犹豫是否选择递归解决方案而不是(可能的,尚未找到的)迭代解决方案。作为比较,您知道更新的代码是比您的函数慢还是快?几乎不需要向代码中添加类型。如果你做得对,大多数列表处理都“足够快”。还请注意,在大多数Lisp编译器中,这将生成SAFETY=0的不安全代码。这太糟糕了。不幸的是,
映射到
无法处理嵌套列表,这正是我要处理的。(我知道我上面的代码不考虑嵌套列表,但我已将其扩展为我文件中的递归函数)如果您知道我可以利用
映射到
到嵌套列表的方法,请告诉我。
(defun add-two-lists (a b c &optional (d c))
  (if a
    (add-two-lists
     (cdr a) (cdr b)
     (cdr (rplaca c (+ (car a) (car b)))) d) d))

(time
 (dotimes (i 1e6)
   (add-two-lists '(1 2 3 4 5)
          '(1 2 3 4 5)
          '(nil nil nil nil nil))))

;; Evaluation took:
;;   0.077 seconds of real time
;;   0.076004 seconds of total run time (0.076004 user, 0.000000 system)
;;   98.70% CPU
;;   214,723,476 processor cycles
;;   0 bytes consed

(defun add-two-lists-1 (list1 list2 list3)
  (loop for a in list1
     for b in list2
     for c on list3 do
       (rplaca c (+ a b))))

(time
 (dotimes (i 1e6)
   (add-two-lists-1 '(1 2 3 4 5)
          '(1 2 3 4 5)
          '(nil nil nil nil nil))))

;; Evaluation took:
;;   0.060 seconds of real time
;;   0.060004 seconds of total run time (0.060004 user, 0.000000 system)
;;   100.00% CPU
;;   169,395,444 processor cycles
;;   0 bytes consed
(defun add-two-lists (a b c &optional (d c))
  (declare (optimize (speed 3) (safety 0)))
  (declare (type list a b c d))
  (if a
    (add-two-lists
     (cdr a) (cdr b)
     (cdr (rplaca
       c 
       (the fixnum
         (+ (the fixnum (car a))
        (the fixnum (car b)))))) d) d))

(time
 (dotimes (i 1e6)
   (add-two-lists '(1 2 3 4 5)
          '(1 2 3 4 5)
          '(nil nil nil nil nil))))

;; Evaluation took:
;;   0.041 seconds of real time
;;   0.040002 seconds of total run time (0.040002 user, 0.000000 system)
;;   97.56% CPU
;;   114,176,175 processor cycles
;;   0 bytes consed

(defun add-two-lists-1 (list1 list2 list3)
  (declare (optimize (speed 3) (safety 0)))
  (loop for a fixnum in list1
     for b fixnum in list2
     for c cons on list3 do
       (rplaca c (the fixnum (+ a b)))))

(time
 (dotimes (i 1e6)
   (add-two-lists-1 '(1 2 3 4 5)
          '(1 2 3 4 5)
          '(nil nil nil nil nil))))

;; Evaluation took:
;;   0.040 seconds of real time
;;   0.040003 seconds of total run time (0.040003 user, 0.000000 system)
;;   100.00% CPU
;;   112,032,123 processor cycles
;;   0 bytes consed