球拍:为嵌套列表的每个元素添加一个数字

时间:2018-08-12 20:58:36

标签: recursion racket

我正在尝试递归地编写此函数。请让我知道Racket文档中是否有用于此功能的库函数。尝试向嵌套列表的每个原子元素添加数字。我保证列表只有2个深度

(define (add_to_all x li) (cond
  ((number? li)                             (+ li x))
  ((and (=(len li)1) (number?(car li)))     (list (add_to_all x (car li))))
  ((=(len li)1)                             (add_to_all x (car li)))
  (else                                     (list (add_to_all x (car li)) `(,@(add_to_all x (cdr li)))))))

用法示例:

(define list_of_lists `((1 2 3)(4 5 6)))
(add_to_all 1 list_of_lists)

错误:返回值的末尾有太多嵌套列表:

'((2 (3 (4))) (5 (6 (7))))

应在的位置

'((2 3 4) (5 6 7))

我认为问题出在最后一个else条件块中,但是我不确定如何“嵌套”尾随部分以得到我想要的东西

3 个答案:

答案 0 :(得分:2)

列表是2深度还是N深度,都没关系,算法可以相同。

(define (add-to-all x xs)
  (cond ((null? xs)
         null)
        ((list? (car xs))
         (cons (add-to-all x (car xs))
               (add-to-all x (cdr xs))))
        (else
         (cons (+ x (car xs))
               (add-to-all x (cdr xs))))))

(add-to-all 10 '((1 2) (3 4) (5 (6 (7 8 9)))))
;; '((11 12) (13 14) (15 (16 (17 18 19))))

可以概括该过程以允许对嵌套列表的所有原子执行任何操作

(define (map* f xs)
  (cond ((null? xs)
         null)
        ((list? (car xs))
         (cons (map* f (car xs))
               (map* f (cdr xs))))
        (else
         (cons (f (car xs))
               (map* f (cdr xs))))))

(define (add-to-all x xs)
  (map* (curry + x) xs))

(add-to-all 10 '((1 2) (3 4) (5 (6 (7 8 9)))))
;; '((11 12) (13 14) (15 (16 (17 18 19))))

答案 1 :(得分:1)

我认为这个问题可以概括为“如何映射嵌套列表?”。

我正在假设该过程还应该在顶级元素上添加数字,例如:(add-to-all 1 '(1 2 (3 4) 5))会产生'(2 3 (4 5) 6)

这是一个基于以下问题的递归解决方案:

(define (add-to-all x li)
  (cond
    [(number? li) (+ li x)]
    [(list? li) (map (curry add-to-all x) li)]
    [else li]))

更通用的解决方案:

(define (map* proc ls)
  (for/list ([elem ls])
    (if (list? elem)
        (map* proc elem)
        (proc elem))))

(define (add-to-all x li)
  (define (proc e)
    (if (number? e)
        (+ x e)
        e))
  (map* proc li))

我在标准的Racket库中没有看到类似map*的过程,但是我只看了几分钟:)。

答案 2 :(得分:0)

有一种比递归更简单的方法:

(define (add x li)
  (for/list ([e li]) (+ x e)))
(define (add_to_all x li)
  (map (lambda(sublist)(add x sublist))
    li))

用法:

(add_to_all 1 '((1 2 3)(4 5 6)))

如果有人知道此操作的库函数,请也回答