如何在Lisp中使用嵌套循环进行配对

时间:2016-10-11 07:35:11

标签: loops while-loop lisp

我正在尝试在Lisp中创建一对配对函数。对函数获得两个输入,然后彼此成对并创建一个列表。这是我的代码:

(defun npair (s1 s2)
  (let ((result '()))
    (cond ((null s1) s2)
          ((null s2) s1)
          (t (loop
               (when (null s1) (return result))
               (while (not (null s2))
                 (setq result (cons (list (car s1) (car s2)) result))
                 (setq s2 (cdr s2)))
               (setq s1 (cdr s1)))))))

此功能应该像(npair '(a b c) '(1 2)) - >一样返回((a 1) (a 2) (b 1) (b 2) (c 1) (c 2))

但我的结果只有((a 1) (a 2))。 请帮忙!

3 个答案:

答案 0 :(得分:3)

如果你想从外循环中积累内部循环中的值,你最好只是简单地累积值,而不是试图通过改变变量来实现它:

(loop for e1 in p1
   append (loop for e2 in p2
             collect (list e1 e2)))

您的格式也是关闭的,自定义是不将终止括号放在新行上。

使用上面的循环结构,您的整个函数将是:

(defun npair (p1 p2)
   (loop for e1 in p1
      append (loop for e2 in p2
                collect (list e1 e2))))

漂亮,简单且易读。

答案 1 :(得分:1)

虽然其他人已经向您展示了更好的替代方案来实现您想要的结果而不是您的实施,但这就是您的实施不起作用的原因:您将s2的值更改为{将null的第一个元素与s1的元素组合在一起时{1}},在处理s2的其余元素之前,永远不会恢复s2的原始值。 (这是为什么你应该首先在不改变输入值的情况下循环输入值的多个很好的理由之一。)

以下是您的实施版本实际可行的版本,因为它不会改变其输入:

s1

答案 2 :(得分:0)

根据它的外观,您希望的结果称为笛卡尔积

我在Scheme编程语言中使用的实现如下:

> (product '(a b c) '(1 2))
 ((a 1) (b 1) (c 1) (a 2) (b 2) (c 2)) 

例如,这里是使用Chez Scheme的输出:

if (triangle->sx1 <= triangle->sx2 <=triangle->sx3)

        {
            triangle->bx = triangle->sx1;
        }
        else if (triangle->sx2 <= triangle->sx1 <= triangle->sx3)
        {
            triangle->bx = triangle->sx2;
        }
        else (triangle->bx = triangle->sx3);


if (triangle->sy1 <= triangle->sy2 <= triangle->sy3)

        {
            triangle->by = triangle->sy1;
        }
        else if (triangle->sy2 <= triangle->sy1 <= triangle->sy3)
        {
            triangle->by = triangle->sy2;
        }
        else (triangle->by = triangle->sy3);


if (triangle->sx1 >= triangle->sx2 >= triangle->sx3)

        {
            triangle->bw = triangle->sx1;
        }
        else if (triangle->sx2 >= triangle->sx1 >= triangle->sx3)
        {
            triangle->bw = triangle->sx2;
        }
        else (triangle->bw = triangle->sx3);


if (triangle->sy1 >= triangle->sy2 >= triangle->sy3)

        {
            triangle->bh = triangle->sy1;
        }
        else if (triangle->sy2 >= triangle->sy1 >= triangle->sy3)
        {
            triangle->bh = triangle->sy2;
        }
        else (triangle->bh = triangle->sy3);