2012-11-09 79 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'中需要第三種情況?我做了一些測試,第一個例子足以找到一個循環。你能提供一個反例嗎? –