计算列表和子列表的元素

时间:2013-11-19 00:24:53

标签: scheme lisp racket

我正在尝试创建一个函数来计算列表中的所有元素,包括其子列表的元素。最初,为了开始,我提出了一个基本功能myList

(define myLength 
  (lambda (L)
    (cond
      ((null? L) 0)
      (else (+ 1 (myLength (cdr L)))))))

然而,它并没有帮助我解释函数调用,如:

(numAtoms '())              "...should be 0"
(numAtoms '(()))            "...should be 0"
(numAtoms '(1 1))           "...should be 2"
(numAtoms '(1 (1 1) 1))     "...should be 4"
(numAtoms '(1 (1 (1 1)) 1)) "...should be 5"

我正在尝试使用lengthnull?list?等基本功能。

3 个答案:

答案 0 :(得分:2)

我认为这里的技巧是想象你如何将输入转换为你想要用来计算总和的代码。让我们以cons'()以及数据中出现的其他原子的形式,以完全展开的形式编写每个输入:

'()               == '()
'(())             == (cons '() '())
'(1 1)            == (cons 1 (cons 1 '()))
'(1 (1 1) 1)      == (cons 1 (cons 1 (cons 1 '())) (cons 1 '()))
'(1 (1 (1 1)) 1)  == ...

现在,看看如果用cons替换+的每一次出现,用'()替换0的每次出现会发生什么,并且每次出现的事件都不是'() 1 '() => 0 == 0 (cons '() '()) => (+ 0 0) == 0 (cons 1 (cons 1 '())) => (+ 1 (+ 1 0)) == 2 (cons 1 (cons 1 (cons 1 '())) (cons 1 '())) => (+ 1 (+ 1 (+ 1 0)) (+ 1 0)) == 4 ... => ... == ... (define (treeduce pair-fn atom-fn tree) (if (pair? tree) (pair-fn (treeduce pair-fn atom-fn (car tree)) (treeduce pair-fn atom-fn (cdr tree))) (atom-fn tree))) 。你有:

cons

请注意,那些 sums 正是您想要的值!基于此,您似乎可能不希望将输入视为列表,而不是从cons单元格构建的。通常,您可以通过指定要应用于处理对的递归结果的函数以及处理树的原子的函数来映射树:

+

然后,您可以将1映射到0,将其他所有内容映射到(define (non-null-atoms tree) (treeduce + (lambda (atom) (if (not (null? atom)) 1 0)) tree)) (如果它是列表)和(non-null-atoms '()) ;=> 0 (non-null-atoms '(())) ;=> 0 (non-null-atoms '(1 1)) ;=> 2 (non-null-atoms '(1 (1 1) 1)) ;=> 4 (non-null-atoms '(1 (1 (1 1)) 1)) ;=> 5 (如果不是):

{{1}}

这会产生您期望的结果:

{{1}}

答案 1 :(得分:0)

以下是您可以使用的递归模板:

(define (num-atoms lst)
  (cond ((pair? lst) (+ (num-atoms <??>) 
                        (num-atoms <??>)))
        ((null? lst) <??>) ; not an atom
        (else <??>)))      ; an atom

下一个示例使用具有累计值(num)作为参数的帮助程序。

(define (num-atoms lst)
  ;; locally defined helper
  (define (helper num lst)
    (cond ((pair? lst) (helper (helper <??> <??>) <??>)) ; recurse with the sum of elements from car
          ((null? lst) <??>)          ; return accumulated value
          (else (helper <??> <??>)))) ; recurse with add1 to num

  ;; procedure starts here
  (helper 0 lst))

希望有所帮助

答案 2 :(得分:0)

my-length适用于任何参数类型,列表或'原子';那么递归算法几乎变得微不足道了:

(define (my-length l)
  (cond ((null? l) 0)
        ((list? l) (+ (my-length (car l)) (my-length (cdr l))))
        (else 1)))  ; atom

> (my-length '(1 (1 (1 1)) 1)))
5