方案 - 函数递归错误
Scheme - Function recursion error
此函数读取列表并交换值,但前提是散列 table 中存在与列表中的元素匹配的键。但是,读入的列表可能包含其他列表,我想递归地检查它。我使用 if (list? elementInList)
来确定我是否正在处理一个列表,因此我可以使用递归调用在该列表中搜索可能需要交换的元素。我试图这样做,但它没有正确处理列表中的列表。我究竟做错了什么?
(define (let-helper L)
(map (lambda (x) (swap x (hash-ref *variable-table* x) L))
(filter (lambda (x)
(if (list? x)
(let-helper x) ;; recursion here
(hash-has-key? *variable-table* x)))
L)))
我建议只 flatten
编辑列表,以便您可以继续使用 map
和 filter
,如下所示:
(define (let-helper L)
(map (lambda (x) (swap x (hash-ref *variable-table* x) L))
(filter (lambda (x) (hash-has-key? *variable-table* x))
(flatten L))))
否则要让它工作,需要在没有 map
和 filter
的情况下编写它,如下所示:
(define (let-helper L)
(let ((action (lambda (x) (swap x (hash-ref *variable-table* x) L)))
(predicate (lambda (x) (hash-has-key? *variable-table* x))))
(let loop ((a '()) (L L))
(if (null? L)
(reverse a)
(if (list? (car L))
(loop (cons (let-helper (car L)) a) (cdr L))
(if (predicate (car L))
(loop (cons (action (car L)) a) (cdr L))
(loop a (cdr L))))))
未测试。
所以只有当散列有键时才应该发生交换,但返回的列表应该仍然有没有交换的元素?如果是这样,那么不从列表中删除元素不是键将解决这个问题:
(define (let-helper L)
(map (lambda (x)
(if (list? x)
(let-helper x)
(if (hash-has-key? *variable-table* x)
(swap x (hash-ref *variable-table* x) L)
x))))
L)
或
(define (let-helper L)
(let ((action (lambda (x) (swap x (hash-ref *variable-table* x) L)))
(predicate (lambda (x) (hash-has-key? *variable-table* x))))
(let loop ((a '()) (L L))
(if (null? L)
(reverse a)
(if (list? (car L))
(loop (cons (let-helper (car L)) a) (cdr L))
(if (predicate (car L))
(loop (cons (action (car L)) a) (cdr L))
(loop (cons (car L) a) (cdr L))))))
此函数读取列表并交换值,但前提是散列 table 中存在与列表中的元素匹配的键。但是,读入的列表可能包含其他列表,我想递归地检查它。我使用 if (list? elementInList)
来确定我是否正在处理一个列表,因此我可以使用递归调用在该列表中搜索可能需要交换的元素。我试图这样做,但它没有正确处理列表中的列表。我究竟做错了什么?
(define (let-helper L)
(map (lambda (x) (swap x (hash-ref *variable-table* x) L))
(filter (lambda (x)
(if (list? x)
(let-helper x) ;; recursion here
(hash-has-key? *variable-table* x)))
L)))
我建议只 flatten
编辑列表,以便您可以继续使用 map
和 filter
,如下所示:
(define (let-helper L)
(map (lambda (x) (swap x (hash-ref *variable-table* x) L))
(filter (lambda (x) (hash-has-key? *variable-table* x))
(flatten L))))
否则要让它工作,需要在没有 map
和 filter
的情况下编写它,如下所示:
(define (let-helper L)
(let ((action (lambda (x) (swap x (hash-ref *variable-table* x) L)))
(predicate (lambda (x) (hash-has-key? *variable-table* x))))
(let loop ((a '()) (L L))
(if (null? L)
(reverse a)
(if (list? (car L))
(loop (cons (let-helper (car L)) a) (cdr L))
(if (predicate (car L))
(loop (cons (action (car L)) a) (cdr L))
(loop a (cdr L))))))
未测试。
所以只有当散列有键时才应该发生交换,但返回的列表应该仍然有没有交换的元素?如果是这样,那么不从列表中删除元素不是键将解决这个问题:
(define (let-helper L)
(map (lambda (x)
(if (list? x)
(let-helper x)
(if (hash-has-key? *variable-table* x)
(swap x (hash-ref *variable-table* x) L)
x))))
L)
或
(define (let-helper L)
(let ((action (lambda (x) (swap x (hash-ref *variable-table* x) L)))
(predicate (lambda (x) (hash-has-key? *variable-table* x))))
(let loop ((a '()) (L L))
(if (null? L)
(reverse a)
(if (list? (car L))
(loop (cons (let-helper (car L)) a) (cdr L))
(if (predicate (car L))
(loop (cons (action (car L)) a) (cdr L))
(loop (cons (car L) a) (cdr L))))))