【问题标题】:A elementary Lisp procedure error一个基本的 Lisp 程序错误
【发布时间】:2012-09-13 04:42:29
【问题描述】:
(define (sum-two-sqrt a b c)

    (cond ((and (<= c a) (<= c b)) sqrt-sum(a b))
           ((and (<= a b) (<= a c)) sqrt-sum(b c))
           ((and (<= b a) (<= b c)) sqrt-sum(a c))
    )
)
(define (sqrt-sum x y)
           (+ (* x x) (*y y))
)
(define (<= x y)
      (not (> x y))

(sum-two-sqrt 3 4 5)

这是我的代码

请帮我解决问题。 :)

我今天才开始学习 Lisp。

之前学过一些 C,但是这两种语言完全不同!

这是问题 定义一个以三个数字作为参数并返回两个较大数字的平方和的过程。

如果你有更好的算法

张贴!

谢谢你:)

【问题讨论】:

  • (sqrt-sum a b) 不是sqrt-sum(a b),为什么还要定义&lt;=?不是已经定义了吗?
  • 好的,我将 sqrt-sum(a b) 更改为 (sqrt-sum a b)。程序现在可以运行,但结果不对。
  • 为了他人的利益,请发布您的解决方案。
  • 下次,描述您的问题。您省略了说明您认为存在问题的原因。

标签: lisp scheme racket


【解决方案1】:

不需要定义&lt;=,它是一个原始操作。修正几个错别字后:

  • sqrt-sum:你错误地调用了程序;左括号必须写在之前过程名称,而不是之后
  • sqrt-sum(*y y) 不正确,你肯定是说(* y y);运算符后的空格。

这应该可行:

(define (sqrt-sum x y)
  (+ (* x x) (* y y)))

(define (sum-two-sqrt a b c)
  (cond ((and (<= c a) (<= c b)) (sqrt-sum a b))
        ((and (<= a b) (<= a c)) (sqrt-sum b c))
        ((and (<= b a) (<= b c)) (sqrt-sum a c))))

或者另一种选择:

(define (sum-two-sqrt a b c)
  (let ((m (min a b c)))
    (cond ((= a m) (sqrt-sum b c))
          ((= b m) (sqrt-sum a c))
          (else (sqrt-sum a b)))))

【讨论】:

  • 您的第二个解决方案相当优雅,对 使用三个参数
  • 在 python 中,我会执行类似 args.remove(min(args)) 的操作,将最小的 arg 从列表中拉出,然后返回 sum(arg **2 for arg in args)。我认为一个 lisp 的翻译可能会更优雅?
  • 我不知道python,但看起来不错。如果您想在功能上做到这一点,您可以制作一个参数列表,按降序对它们进行排序,获取前两个元素,将它们映射到它们的正方形,将两个项目的结果列表相加以产生您的结果。跨度>
  • 来吧伙计们,删除元素?排序?映射?那是矫枉过正!我的第二个解决方案很简单,因为它可以获得固定数量的参数
  • 是的,你对这个玩具练习有意见,但他们在学校教 lisp 的部分原因是为了理解这些概念,对吧?公平地说,我的解决方案是 2 行短代码加上检查传入的 args 数量是否为 3,而不是完全膨胀。
【解决方案2】:

根据@J.Spiral 的建议并得到@River 的支持,以下 Racket 代码对我来说很好读:

#lang racket

(define (squares-of-larger l)
  (define two-larger (remove (apply min l) l))
  (for/sum ([i two-larger]) (* i i)))

(squares-of-larger '(3 1 4)) ;; should be 25

请注意,这个解决方案是完全可用的,因为“删除”只是返回一个新列表。

还要注意,这甚至与 HtDP 不在同一个社区;我只是想简明扼要地表达一下,炫耀一下for/sum。

【讨论】:

    【解决方案3】:

    我这里没有 Scheme 解释器,但下面似乎比其他建议短:) 所以它在 CL 中,但在 Scheme 中看起来应该非常相似。

    (defun sum-two-sqrt (a b c)
      (let ((a (max a b))
            (b (max (min a b) c)))
        (+ (* a a) (* b b))))
    

    在 Scheme 中,这将转化为:

    (define (sum-two-sqrt a b c)
      (let ((a (max a b))
            (b (max (min a b) c)))
        (+ (* a a) (* b b))))
    

    【讨论】:

      【解决方案4】:

      算法好像有效,转一下

      *y
      

      * y
      

      空格在这里很重要,否则你告诉解释器你想使用函数*y

      之后添加一个右括号
      (define (<= x y) (not (> x y))
      
      sqrt-sum(a b) 
      

      转向

      (sqrt-sum a b)
      

      其他 sqrt-sum 调用也是如此

      编辑:也有可能:

      (define (square a) (* a a))
      (define (square-sum a b c)
          (- (+ (square a) 
                (square b)
                (square c))
             (square (min a b c))))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-07
        • 1970-01-01
        • 1970-01-01
        • 2014-03-08
        • 1970-01-01
        相关资源
        最近更新 更多