在Common Lisp中等效的有序对的循环


誓言你好
2025-02-05 09:28:59 (1月前)


假设您有一个列表,并希望生成所有有序元素对的列表,例如列表是’(1 3 5 7 9),所需的结果是

((1.1)(1.3)(1.5)(1.7)(1.9)(3.3)(3.5)(……

2 条回复
  1. 0# Let us fly | 2019-08-31 10-32




    通过使用

    map

    仅限家庭功能
    </强>



    在我看来,这是非常lispy(也许是一个解决方案

    loop

    -haters):




    1. (defun 1st-conses (l)
      (mapcar #’(lambda (x) (cons (car l) x)) l))

    2. (mapcan #’1st-conses (maplist #’identity ‘(1 3 5 7 9))
      ;; ((1 . 1) (1 . 3) (1 . 5) (1 . 7) (1 . 9) (3 . 3) (3 . 5) (3 . 7) (3 . 9)
      ;; (5 . 5) (5 . 7) (5 . 9) (7 . 7) (7 . 9) (9 . 9))

    3. </code>



    仅通过递归
    </强>



    和尾部调用递归解决方案

    loop

    -haters:




    1. (defun 1st-conses (l)
      (labels ((.1st-conses (l fst acc)
      (cond ((null l) (nreverse acc))
      (t (.1st-conses (cdr l) fst (cons (cons fst (car l))
      acc))))))
      (.1st-conses l (car l) ‘())))

    2. (defun combine-down (l &optional (acc ‘()))
      (cond ((null l) acc)
      (t (pairing-down (cdr l) (nconc acc (1st-conses l))))))

    3. (combine-down ‘(1 3 5 7 9))
      ;; ((1 . 1) (1 . 3) (1 . 5) (1 . 7) (1 . 9) (3 . 3) (3 . 5) (3 . 7) (3 . 9)
      ;; (5 . 5) (5 . 7) (5 . 9) (7 . 7) (7 . 9) (9 . 9))

    4. </code>





    loop

    功能
    </强>



    这三个函数的融合版本在其他答案中给出:




    1. (defun tails (l)
      (loop for x on l collect x))

    2. (defun 1st-conses (l)
      (loop for x in l collect (cons (car l) x)))

    3. (loop for l in (tails ‘(1 3 5 7 9))
      nconc (1st-conses l))

    4. </code>



    具有小功能的更通用解决方案
    </强>



    结合这三个功能中的任何一个 - 每个功能都带有一个

    map

    -version,a

    loop

    -version和尾调用递归版本。 - 所以你可以选择创建一个




    • 纯粹

      map




    • 纯粹

      loop

      解决方案或


    • 纯粹的递归解决方案。



    或者您




    • 故意混淆他们;)



    功能是:




    1. ;;;;;;;;;;;;;;;;;;;;
      ;; function collecting all cdrs of a list:
      ;; (tails ‘(a b c))
      ;; ;; returns: ((A B C) (B C) (C))
      ;;;;;;;;;;;;;;;;;;;;

    2. ;; with maps
      (defun tails (l)
      (maplist #’identity l))

    3. ;; with loop
      (defun tails (l)
      (loop for x on l collect x))

    4. ;; tail-call-recursion
      (defun tails (l &optional (acc ‘()))
      (cond ((null l) (nreverse acc))
      (t (tails (cdr l) (cons l acc)))))

    5. ;;;;;;;;;;;;;;;;;;;;
      ;; function collecting car of a list consed with each list element
      ;; (1st-conses ‘(a b c))
      ;; ;; returns: ((A . A) (A . B) (A . C))
      ;;;;;;;;;;;;;;;;;;;;

    6. ;; with maps
      (defun 1st-conses (l)
      (mapcar #’(lambda (x) (cons (car l) x)) l))

    7. ;; with loop
      (defun 1st-conses (l)
      (loop for x in l collect (cons (car l) x)))

    8. ;; tail-call-recursion
      (defun 1st-conses (l)
      (labels ((.1st-conses (l fst acc)
      (cond ((null l) (nreverse acc))
      (t (.1st-conses (cdr l) fst (cons (cons fst (car l))
      acc))))))
      (.1st-conses l (car l) ‘())))

    9. ;;;;;;;;;;;;;;;;;;;;
      ;; applying the second function on the first functions results
      ;; (combine-down ‘(a b c))
      ;; ;; returning: ((A . A) (A . B) (A . C) (B . B) (B . C) (C . C))
      ;;;;;;;;;;;;;;;;;;;;

    10. ;; with maps
      (defun combine-down (l)
      (mapcan #’1st-conses (tails l)))

    11. ;; with loop
      (defun combine-down (l)
      (loop for x in (tails l)
      nconc (1st-conses x)))

    12. ;; with tail-call-recursion
      (defun combine-down (l)
      (labels ((.combine-down (l acc)
      (cond ((null l) acc)
      (t (.combine-down (cdr l)
      (nconc acc
      (1st-conses (car l))))))))
      (.combine-down (tails l) ‘())))

    13. </code>


    然后:




    1. (combine-down ‘(1 3 5 7 9))
      ;; ((1 . 1) (1 . 3) (1 . 5) (1 . 7) (1 . 9) (3 . 3) (3 . 5) (3 . 7) (3 . 9)
      ;; (5 . 5) (5 . 7) (5 . 9) (7 . 7) (7 . 9) (9 . 9))

    2. </code>



    势在必行
    </强>



    为了好玩,我尽可能地翻译了命令式cpp代码 -
    因为作为一种真正的多范式语言…:




    1. (let ((arr ‘(1 3 5 7 9))
      (res ‘()))
      (loop for i from 0 below 5 by 1
      do (loop for j from i below 5 by 1
      do (setq res (cons (cons (elt arr i)
      (elt arr j))
      res))))
      (nreverse res))

    2. </code>


    它正确返回:




    1. ((1 . 1) (1 . 3) (1 . 5) (1 . 7) (1 . 9) (3 . 3) (3 . 5) (3 . 7) (3 . 9)
      (5 . 5) (5 . 7) (5 . 9) (7 . 7) (7 . 9) (9 . 9))

    2. </code>

登录 后才能参与评论