【问题标题】:Common Lisp - Gentle introduction to symbolic computation: Excercise 4.4Common Lisp - 符号计算的简单介绍:练习 4.4
【发布时间】:2016-09-27 00:02:43
【问题描述】:

我正在使用 clisp 学习 Common Lisp,并输入了以下代码:

(defun ordered (x y)
   (if (< x y)
       (list x y)
       (list y x)))

(setq l (ordered 28 49))
(print l)
(setq l (ordered 49 28))
(print l)

期待这些答案: (28 49) (49 28)

得到以下答案: (28 49) (28 49)

在本书的解决方案中,我发现了相同的函数定义。 有什么问题?

【问题讨论】:

  • 欢迎来到 Stack Overflow!您看到的结果对我来说很有意义 - 能否请您附上您尝试完成的练习?
  • 我希望您得到确切的答案。这就是ordered 应该做的,不是吗?
  • 练习是使用 if 与一个比较子句和两个结果子句,一个用于比较 true,一个用于比较 nil (false)。答案 1 可以,因为 28 小于 49。答案 2 不是因为 49 不小于 28,这会产生 nil。结果第 2 条应该起作用并产生 (49 28) 永远不会发生的事情。
  • 现在我在 REPL 中检查了这个表达式,并用 (print ') 替换了 (list x y) 和 (list y x)。现在我得到了预期的结果。在我看来,好像 if 特殊函数中的列表表达式只用 (list x y) 计算了一次,然后在两个结果子句中使用,尽管 x y 的值。非常感谢 if 特殊功能的这种行为的详细信息。还是我做了错误的假设?
  • 调用(ordered 49 28)时,x绑定49,y绑定28。由于(&lt; x y)为false,所以函数的结果是第三个生成的列表if 的参数(else 子句)。该子句构建一个列表,其中第一个元素是y, 28,第二个元素是x, 49。这就是返回值是(28 49) 的原因。有序函数接受两个元素并对它们进行排序。

标签: lisp common-lisp clisp


【解决方案1】:

你的代码

(defun

定义一个函数,

        ordered 

命名为“有序”,

                (x y)

它需要两个参数,在其正文中将被称为“x”和“y”,因此在接收参数时(即已使用两个值调用,例如(ordered 49 28)

   (if (< x y)

它会比较它们,如果第一个小于第二个,它将产生

       (list x y)

相同的两个值重新打包在一个列表中(即'(49 28)); 否则,如果第一个值小于第二个,

       (list y x)))

它将生成包含第二个值的列表first,然后是第一个参数值(即'(28 49))。

那么,比较 4928 的情况是什么?


一般地阅读这段代码,我们可以说如果它接收到 smaller 数字作为它的 first 参数,它将首先产生较小的数字,然后产生较大的数字,在结果列表中;

如果它接收到 smaller 数字作为其 second 参数,它将在结果列表中首先生成较小的数字,然后生成较大的数字。 p>

读回来,我们可以看到这个描述可以进一步简化为一个简单的陈述:它总是会在结果列表中首先产生 ______ 个数字,然后是 ______ 个。


解决这个问题的另一种方法是写下由该定义创建的函数,

( lambda (x y)  (if   (< x y)    (list x y)    (list y x) ) )

然后象征性地跟随它的应用:

(   ( lambda (x y)  (if   (< x y)    (list x y)    (list y x) ) )
    49
    28  )

==

(let  (   (x   49)
          (y   28)
      )
                    (if   (< x y)    (list x y)    (list y x) ) )

==

(let  (   (x   49)
          (y   28)
      )
                    (if   (< 49 28)  (list x y)    (list y x) ) )

==

(let  (   (x   49)
          (y   28)
      )
                    (if   FALSE      (list x y)    (list y x) ) )

==

(let  (   (x   49)
          (y   28)
      )
                                                   (list y x)   )

==

(let  (   (x   49)
          (y   28)
      )
                                                   (list 28  49) )

==

(list  28  49)    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-21
    • 2010-11-22
    相关资源
    最近更新 更多