Lisp 用于反转2-list列表元素的Scheme函数
这是EOPL的一个练习。 过程(反转lst)获取lst,lst是一个由两个列表组成的列表,并返回一个列表,每个列表都反转Lisp 用于反转2-list列表元素的Scheme函数,lisp,scheme,Lisp,Scheme,这是EOPL的一个练习。 过程(反转lst)获取lst,lst是一个由两个列表组成的列表,并返回一个列表,每个列表都反转 (define invert (lambda (lst) (cond((null? lst ) '()) ((= 2 (rtn-len (car lst))) ( cons(swap-elem (car lst)) (invert (cdr lst)))) ("List i
(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-list的单独元素?
此时,执行继续到下一个成员,如果当前成员不是2-List,则将当前成员替换为“List is not a 2-List”。因此,您的invert版本似乎实际返回了不同拓扑的列表。如果您在
'((12)(34))
上执行(反转…
,您将返回'((2.1)(4.3))
,这是一个消费列表,而不是列表
我编写了一个版本的invert,它维护列表拓扑,但它不是尾部递归的,所以在递归时它将最终维护一个调用堆栈
(define (invert lst)
(if (null? lst)
lst
(cons (list (cadar lst) (caar lst))
(invert (cdr lst)))))
如果您想要一个模仿您反转行为的版本,请将倒数第二行中的
列表
替换为cons
。如果您希望它在出现故障时尽早退出,请尝试调用/cc
(call-with-current-continuation
(lambda (exit)
(for-each (lambda (x)
(if (negative? x)
(exit x)))
'(54 0 37 -3 245 19))
#t))
===> -3
(摘自)
使用当前continuation调用
(或简称call/cc
)所做的是将函数被调用的点传递到函数中,这提供了一种类似于C中返回语句的方法。它还可以做更多的事情,因为您可以存储continuation,或将多个continuation传递到函数中,对于成功和失败,调用不同的过程。EOPL语言提供了EOPL:error
过程,以便提前退出并显示错误消息。本书第15页(第3版)介绍了这一点
EOPL语言还包括标准方案中的map
过程。尽管本书中可能没有使用它,但您仍然可以使用它获得比显式递归更短的解决方案。您还可以使用Scheme的标准长度过程
#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))))
包含任意数量或顺序子列表的反向列表
(define (reverse! lst)
(if (null? lst) lst
(if (list? (car lst))
(append (reverse! (cdr lst)) (cons (reverse! (car lst)) '()))
(append (reverse! (cdr lst)) (list (car lst))))))
非常感谢。如何处理列表并退出单个元素不是2列表的过程。您的过程只是跳过了额外的元素。非常感谢。虽然这超出了我目前的理解水平。:)