2012-11-09 46 views
1

我是新来的计划,有人能给我一些关于如何获得“中间元素从列表?”的想法吗?从计划中获取列表中的中间元素

+0

有趣的问题(特别是如果你只想遍历列表一次)。如果列表中包含偶数个元素,会发生什么?如果列表为空,应该发生什么? –

回答

4

这是我的解决方案。它基于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
  • 如果给出不正确的列表(包括非列表),召唤鼻子恶魔。
+0

谢谢,这让我走了。但是如果用户给出的参数不是列表会发生什么?我们可以显示如下警告:(show“USAGE:(middle-element [LIST])”))也许? –

+0

你正在和Nathalie D一样的课程,是吗? :-P同样的非标准'show'功能,相同的使用信息等等。我的老实说,检查参数类型的最好方法是通过Racket的[合同](http://docs.racket-lang.org/guide /contracts.html)。我不太了解合同,所以我无法帮助。我绝对不能帮助你的课程使用'show',因为这甚至不是标准的Scheme。 –

+0

@ ChrisJester-Young我很好奇,为什么'cond'中需要第三种情况?我做了一些测试,第一个例子足以找到一个循环。你能提供一个反例吗? –