我必须创建一个返回列表反向的Racket方案。我不能使用内置的反向方法或类似的东西。 到目前为止,我已经做了一切可以逆转,但问题是我的方法没有返回值,而是保留它。 这就是我所做的:
#lang racket
(define (rev x)
(define n '())
(define i (- (length x) 1))
(let loop ()
(when (> i -1)
(set! n (append n (list (list-ref x i))))
(set! i (sub1 i))
(loop)))
(set! x n)
"in method display"
(displayln x))
"display"
(define letters'("a" "b" "c"))
(rev letters)
"in main program display"
(displayln letters)
当我在方法中打印时,我得到(c b a)但是当我从主程序打印时,我得到(a b c)这意味着我的方法没有返回值。我该怎么办?
此方法返回void,如何使其返回值?
答案 0 :(得分:3)
在一个过程中评估的最后一个表达式是“返回”的内容,因此在rev
中它是(displayln x)
并且它返回一个void。如果您将最后一个元素更改为n:
(define (rev x)
(define n '())
(define i (- (length x) 1))
(let loop ()
(when (> i -1)
(set! n (append n (list (list-ref x i))))
(set! i (sub1 i))
(loop)))
(set! x n)
"in method display"
(displayln x)
n) ; evaluates n last!
它也会返回结果。这个代码对于Scheme来说是非常必要的。在不改变解决方法的情况下,您可以将n
和i
移至指定的let
:
(define (rev x)
(let loop ((n '())
(i (- (length x) 1)))
(if (> i -1) ; if i is positive
(loop (append n (list (list-ref x i))) ; then call loop with new n and
(sub1 i)) ; new i
n))) ; else return n
更惯用的解决方案是cons
从开始到结束的元素到累加器。第一个元素将自动成为最后一个元素:
(define (rev lst)
(let loop ((lst lst) ; we start with the whole list
(acc '())) ; out initial acc is the empty list
(if (<??> lst) ; if lst is empty
<??> ; then return accumulator
(loop (<??> lst) ; else we recurse with the cdr of the list
(cons <??> acc))))) ; while adding the car to the beginning of acc