【问题标题】:Get the middle elements from List in scheme从scheme中的List中获取中间元素
【发布时间】:2012-11-09 10:48:30
【问题描述】:

我是 scheme 的新手,有人可以给我一些关于如何获取“列表中的中间元素”的想法吗?

【问题讨论】:

  • 有趣的问题(特别是如果您只想遍历列表一次)。如果列表有偶数个元素会发生什么?如果列表为空应该怎么办?

标签: scheme


【解决方案1】:

这是我的解决方案。它基于tortoise-and-hare algorithm(用于需要检测循环列表的任何类型的列表遍历),因此它不会比理智的列表遍历做更多的工作。 :-)

(define (middle-elements lst)
  (if (null? lst) '()
      (let loop ((tortoise lst)
                 (hare (cdr lst)))
        (cond ((eq? tortoise hare) #f)
              ((null? hare) (list (car tortoise)))
              ((null? (cdr hare)) (list (car tortoise) (cadr tortoise)))
              (else (loop (cdr tortoise) (cddr hare)))))))

涵盖以下几种情况:

  • 如果给定一个空列表,则返回一个空列表。
  • 如果给定一个包含奇数个元素的列表,则返回一个包含中间元素的单例列表。
  • 如果给定一个包含偶数个元素的列表,则返回一个包含两个中间元素的列表。
  • 如果给定一个循环列表,则返回#f
  • 如果给出不正确的列表(包括非列表),则召唤鼻恶魔。

【讨论】:

  • 谢谢,这让我继续前进。但是如果用户给的参数不是一个列表会怎样呢?我们可以显示类似的警告:(show " USAGE: (middle-element [LIST])")) 吗?
  • 你和 Nathalie D 上的课一样,不是吗? :-P 相同的非标准show 函数,相同的使用信息等。老实说,检查参数类型的最佳方法是通过Racket 的contracts。我不太了解合同,所以我无能为力。而且我绝对无法帮助您的课程使用show,因为这甚至不是标准的Scheme。
  • @ChrisJester-Young 我很好奇,为什么cond 中的第三种情况是必要的?我做了几个测试,第一个案例足以找到一个循环。能举个反例吗?
  • @ÓscarLópez 你说的完全正确,这完全是多余的,现在我想起来了。一旦第三种情况匹配,那么根据定义,第一种情况将在下一次循环中匹配。
猜你喜欢
  • 1970-01-01
  • 2019-05-22
  • 1970-01-01
  • 1970-01-01
  • 2014-09-17
  • 1970-01-01
  • 2017-12-28
  • 2012-07-30
  • 1970-01-01
相关资源
最近更新 更多