【问题标题】:Counting elements of a list and sublists计算列表和子列表的元素
【发布时间】:2013-12-02 08:52:25
【问题描述】:

我正在尝试创建一个函数来计算列表中的所有元素,包括其子列表的元素。最初,为了开始,我想出了一个基本功能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? 等基本功能。

【问题讨论】:

  • 您将两种情况混合在一起。如果 L 的车是一个列表,你想做一些不同的事情。
  • 有时我想知道为什么老师们还要费心布置作业......希望他们不要试图根据它来给努力或成就评分。

标签: scheme lisp racket


【解决方案1】:

我认为这里的诀窍是想象如何将输入转换为要用于计算总和的代码。让我们以完全扩展的形式编写您的每个输入,以 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
...                                         => ...                         == ...

请注意,这些 sums 正是您想要的值!基于此,您似乎不希望将输入视为 list,而是将其视为由 cons 单元构建的 tree。通常,您可以通过指定一个函数来映射树,以应用于处理一对递归的结果,并指定一个函数来处理树的原子:

(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+ 的映射,如果它是一个列表,则将其他所有内容映射到 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

【讨论】:

  • 对不起,我还是个球拍初学者。谓词,配对是什么?而treeduce呢?
  • @user2989977 我(希望我)已经澄清并简化了解释。
【解决方案2】:

这是一个您可以使用的递归模板:

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

希望对你有帮助

【讨论】:

    【解决方案3】:

    使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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-14
      • 1970-01-01
      • 1970-01-01
      • 2023-02-25
      • 2017-03-31
      相关资源
      最近更新 更多