【问题标题】:A scheme procedure that returns a list of every other element一个返回所有其他元素列表的方案过程
【发布时间】:2012-10-30 09:09:47
【问题描述】:

我在 Scheme 中实现这个程序时遇到了一些麻烦,尽管我认为我已经完成了 90% 的工作。不幸的是,我需要对此有点模糊,因为这是一项家庭作业。 我想(A B C D)返回(B D)。但我收到一条错误消息,指出作为参数传递给安全车的对象 () 不是一对 | " 这是我的代码:

(DEFINE (other_el lis)
  (COND
   (( NULL? lis ) '())
   ((LIST? lis)
    (append (CADR lis) (other_el (CDR lis))))
   (ELSE (show " USAGE: (other_el [LIST])"))))

【问题讨论】:

  • 你熟悉函数cddr吗?

标签: scheme


【解决方案1】:

在我演示正确的代码之前,应该提到这段代码的一些小问题。

  1. 不要将过程名称大写,例如 cdr 和在 Scheme 中定义。
  2. 不要手动显示错误消息。使用例外。
  3. 您应该始终缩进您的代码。 (编辑:看起来有人编辑了问题的代码以包含缩进)

不管怎样,这是你要找的功能:

(define (evens lst)
  (if (or (null? lst)             ; if the list is empty 
          (null? (cdr lst)))      ; or the list has a single element
      '()                         ; then return the empty list
      (cons (cadr lst)            ; otherwise `cons` the second element
            (evens (cddr lst))))) ; and recursively advance two elements

我在 DrRacket 5.3 中测试了该函数,并且 (evens '(A B C D)) 返回 '(B D),正如您指定的那样。如果您有任何问题,请告诉我。祝你作业顺利!

【讨论】:

  • 当用户输入一个不是“列表”的参数而不是让解释器执行它时,我希望能够打印特定的错误消息。我试图按照你的逻辑去做,但我迷路了:)提前谢谢
  • 包含您自己的错误消息的最佳方法是让另一个函数检查列表并进行错误处理,然后调用我给您的函数(即 Oscar 在他的回答)。
  • 这是一个糟糕的答案,解决方案很容易是O(n)(请参阅this implementation),但在条件下使用length 使其成为O(n^2)。您应该在每次迭代时检查列表的长度,永远
  • 谢谢 Oscar,我将代码更改为您在实现中提供的代码(我会直接删除我的答案,但不幸的是它已经被接受了)。
【解决方案2】:

这个问题比您提出的上一个问题要简单得多。请记住,您不必在每一步都计算长度(这可能非常低效),或者使用附加操作来解决它(改用cons);这是答案的结构,因为它看起来像家庭作业,我让你填空:

(define (every-other lst)
  (if (or <???>                    ; if the list is empty 
          <???>)                   ; or the list has a single element
      <???>                        ; then return the empty list
      (cons <???>                  ; otherwise `cons` the second element
            (every-other <???>)))) ; and recursively advance two elements

如果您需要先进行一些错误检查,请使用另一个函数并在确定参数正确后调用上述过程:

(define (other_el lst)
  (if (list? lst)
      (every-other lst)
      (error "USAGE: (other_el [LIST])")))

像这样使用它:

(other_el '(A B C D E G))
=> '(B D G)

【讨论】:

  • 是否有语法来检查列表是否有单个元素,就像我们检查空列表的方式(null?lst)一样?对不起,如果这太基本了,我对这门语言还是陌生的。 Google 帮不上忙 :)
  • @NathalieD 当然可以。只需检查当前元素之后的下一个元素是否为空列表:(null? (cdr lst))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-03
  • 1970-01-01
  • 2022-06-17
  • 1970-01-01
  • 1970-01-01
  • 2016-08-06
相关资源
最近更新 更多