方案 - 函数递归错误 [英] Scheme - Function recursion error

查看:187
本文介绍了方案 - 函数递归错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个函数读取列表并交换值,但只有在哈希表中有一个与列表中的元素相匹配的关键字时。但是,读入的列表可能包含其他列表,我想要递归检查。我使用 if(list?elementInList)来确定我是否正在处理一个列表,所以我可以在那个列表中搜索可能需要使用递归调用交换的元素。我试图做到这一点,但它没有正确处理列表中的列表。我究竟做错了什么?

 (define(let-helper L)
(map(lambda(x)(swap x(hash-ref *(变量表* x)L))
(lambda(x)
(if(list?x)
(let-helper x);; recursion here
(hash-has-key?* variable-table * x)))
L)))


解决方案

我建议只是 flatten 列表,以便继续使用 map 过滤器像这样:

  (let-helper L)
(map(lambda(x)(swap x(hash-ref * variable-table * x)L))
(filter(lambda(x)关键?*变量表* 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? *(变量表* x))))

(let循环((a'())(LL))
(if(null?L)

(if(list?(car L))
(cons(let-helper(car L))a)(cdr 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? *变量表* x)
(交换x(hash-ref *变量表* x)L)
x))))
L)




$ (define(let-帮助者L)
(let((动作(lambda(x)(交换x(hash-ref *变量表* x)L)))
(谓词(lambda(x) -key * * variable-table * x))))

(let loop((a'())(LL))
(if(null?L)
(反向a)
(if(list?(car L))
(cons(let-helper(car L))a)(cdr L))
(if (car L))
(loop(cons(action(car L))a)(cdr L))
(loop(cons(car L)a)(cdr L))))))


This function reads in a list and swaps values, but only when there's a key in the hash table that matches an element in the list. However, the list that is read in could contain other lists, and I want to check this recursively. I use if (list? elementInList) to determine whether I'm dealing with a list, so I can search that list for elements that may need to be swapped using a recursive call. I tried to do this but it's not handling the lists within the list correctly. What am I doing wrong?

(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)))

解决方案

I'd suggest just flattening the list so that you can continue to use map and filter like this:

(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))))

Otherwise to get it to work would require writing it without map and filter like this:

(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))))))

Untested.


So the swap should only occur if the hash has the key but the returned list should still have the elements that weren't swapped? If so then not removing the element from the list of it isn't a key would fix that like this:

(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)

Or

(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))))))

这篇关于方案 - 函数递归错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆