【问题标题】:Scheme getting last element in list方案获取列表中的最后一个元素
【发布时间】:2012-10-21 22:14:43
【问题描述】:

我正在尝试编写一个简单的方案函数来返回列表的最后一个元素。我的功能看起来应该可以工作,但我设法在某些事情上失败了:

(define (last_element l)(
  (cond (null? (cdr l)) (car l))
  (last_element (cdr l))
))

(last_element '(1 2 3)) should return 3

DrRacket 不断给我错误:

mcdr: contract violation
  expected: mpair?
  given: ()

既然(null? '()) 是真的,我不明白为什么这不起作用。

这是一个我认为我需要用于家庭作业的函数(编写函数last-element不是作业),并且说明说我不能使用内置函数reverse,所以我可以'不要只做(car (reverse l))

如何修复此功能?

【问题讨论】:

  • 如果你的函数传入空列表会发生什么?当然,您的讲师可能不在乎。他或她有没有说过你可以对数据做出什么假设?对于家庭作业,我认为折扣非列表数据可能是合理的,但在列表上下文中,空列表是合理的预期。其实有一种简单的处理方式,也能合理处理其他非列表数据……

标签: scheme racket r5rs


【解决方案1】:

你可以通过调用来检索列表的最后一个元素

(define (lastElem list) (car (reverse list)))

或者,递归使用 if 内置

(define (last list) (if (zero? (length (cdr list))) (car list) (last (cdr list))))

【讨论】:

    【解决方案2】:

    你也可以这样做。首先通过 cdring 找到列表的长度。然后使用 list-ref x 给出列表的 x 元素。 例如 list-ref yourlistsname 0 给出第一个元素(基本上是列表的汽车)和 (list-ref yourlistsname (- length 1)) 给出列表的最后一个元素。

    【讨论】:

      【解决方案3】:

      你的语法完全错误。您在函数体周围有一组额外的括号,在 cond 子句周围还不够,而且您的递归案例甚至不在 cond 内,因此无论测试成功还是失败都可以完成。以下程序应该有效:

      (define (last_element l)
        (cond ((null? (cdr l)) (car l))
              (else (last_element (cdr l)))))
      

      【讨论】:

      • @calccrypto 这个答案的半完整版本是你几乎所有的单个元素都是正确的。请记住,括号与花括号不同。你会想要打破在第一行“打开(”并将)s 放在自己的行上的习惯。此外,让 DrRacket 指导您使用缩进。你很快就会掌握它的窍门。
      【解决方案4】:

      补充一点:在专业级 Racket 中,last 函数是 racket/list 库的一部分。

      【讨论】:

        猜你喜欢
        • 2011-06-27
        • 1970-01-01
        • 2017-02-18
        • 1970-01-01
        • 1970-01-01
        • 2022-01-01
        • 2010-10-30
        • 1970-01-01
        • 2022-11-15
        相关资源
        最近更新 更多