2011-02-18 52 views
1

這是EOPL的練習。 過程(反轉lst)獲取lst,它是2列表的列表,並返回一個列表,每個2列表反轉。Scheme反轉2列表中的元素的函數

(define invert 
    (lambda (lst) 
    (cond((null? lst) 
     '()) 
     ((= 2 (rtn-len (car lst))) 
     (cons(swap-elem (car lst)) 
       (invert (cdr lst)))) 
     ("List is not a 2-List")))) 

;; Auxiliry Procedure swap-elements of 2 element list 

(define swap-elem 
    (lambda (lst) 
    (cons (car (cdr lst)) 
      (car lst)))) 

;; returns lengh of the list by calling 
(define rtn-len 
    (lambda (lst) 
    (calc-len lst 0)))   

;; calculate length of the list 
(define calc-len 
    (lambda (lst n) 
    (if (null? lst) 
     n 
     (calc-len (cdr lst) (+ n 1))))) 

這似乎工作,但看起來很冗長。這可以縮短或寫在更優雅的方式? 如何在任何單個元素中停止處理不是2列表? 目前執行進入下一個成員,並且如果當前成員不是2列表,則用「列表不是2列表」替換當前成員。

回答

1

EOPL語言提供了eopl:error過程以提前退出並顯示錯誤消息。它在該書的第15頁介紹(第3版)。

EOPL語言也包括標準Scheme中的map過程。雖然本書可能不會使用它,但仍然可以使用它獲得比具有明確遞歸的解決方案更短的解決方案。您也可以使用Scheme的標準length程序。

#lang eopl 

(define invert 
    (lambda (lst) 
    (map swap-elem lst))) 

;; Auxiliary Procedure swap-elements of 2 element list 

(define swap-elem 
    (lambda (lst) 
    (if (= 2 (length lst)) 
     (list (cadr lst) 
       (car lst)) 
     (eopl:error 'swap-elem 
        "List ~s is not a 2-List~%" lst)))) 
1

因此,您的翻版版本實際上會返回不同拓撲的列表。如果您在'((1 2) (3 4))上執行(invert ...),則會返回'((2 . 1) (4 . 3)),這是一個列表的列表,而不是列表。

我寫了一個維護列表拓撲的反轉版本,但它不是尾遞歸的,所以它最終會在遞歸時維護一個調用堆棧。

(define (invert lst) 
    (if (null? lst) 
     lst 
     (cons (list (cadar lst) (caar lst)) 
      (invert (cdr lst))))) 

如果你想模仿你的行爲反轉的一個版本,在第二次更換listcons到最後一行。

+0

非常感謝。如何處理列表並退出單個元素的過程不是2列表。您的過程只是跳過額外的元素。 – sudhirc 2011-02-18 15:59:12

1

如果您希望在失敗時儘早退出,請嘗試調用/ cc。

(call-with-current-continuation 
    (lambda (exit) 
    (for-each (lambda (x) 
       (if (negative? x) 
        (exit x))) 
       '(54 0 37 -3 245 19)) 
    #t)) 
          ===> -3 

(來自http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_idx_566兩者)​​

什麼call-with-current-continuation(或call/cc,對於短)所做的是通過在函數調用到函數的點,它提供了一種有東西類似於一個它還可以做更多的事情,因爲你可以存儲延續,或者將多個傳遞給一個函數,另一個函數被稱爲成功和失敗。

+0

非常感謝。儘管目前這超出了我的理解水平。:) – sudhirc 2011-02-18 16:16:03