1

我正在尝试编写一个计算列表中所有项目的 Scheme 函数,但与可用的长度函数不同,它也会计算内部列表,因此 countAll '(a (ab)) 将返回 3 而不是 2。

第一个检查是空列表,第二个应该检查列表的头部当前是否是一个列表本身,然后它应该将该列表的长度添加到总数中并调用下一个递归调用,如果它不是' t,它应该简单地跳到第三部分,这将对总数加一并递归调用该函数。

我遇到了语法错误,我不确定我的方法。我会以正确的方式解决这个问题吗?有没有更好/更简单的方法来做到这一点?

(define countAll 
  (lambda (list)

    (if (null? list)
        0

        ((if (list? (car list)
                    (+ length (car list)
                       (countAll (cdr list))))))

        (+ 1
           (countAll (cdr list))))))     
  (+ 1
   (countAll(cdr list)
  )))))
4

3 回答 3

2

你把括号弄得一团糟。我强烈建议使用cond重写它,如

(cond
  ((null? lst) 0)
  ((list? (car lst)) (???))
  (else (???)))

这将使您更容易看到您在做什么,并且不太可能弄乱括号。除非在最简单的情况下,否则嵌套 if 确实是要避免的。

你的方法几乎是正确的,但你错过了一些东西。您对评估为真时会发生什么做出了很大的假设。(list? (car lst))你能想到它是什么吗?如果你足够认真地考虑它,你会意识到你不能在这里使用长度函数。

于 2012-10-22T15:21:52.790 回答
1

此类问题的解决方案遵循一个众所周知的结构,如果您愿意,可以使用配方,用于遍历列表列表。这看起来像家庭作业,所以我将帮助您了解总体思路,然后您继续填写空白:

(define (countAll lst)
  (cond ((null? lst)               ; if the list is empty.
         <???>)                    ; then it doesn't have any elements
        ((not (list? (car lst)))   ; if the first element in the list is not a list
         (<???> (countAll <???>))) ; add one and advance the recursion over the `cdr`
        (else                      ; otherwise
         (+ (countAll <???>)       ; add the result of the recursion over the `car`
            (countAll <???>)))))   ; with the result of the recursion over the `cdr`

如果您需要更多帮助来理解如何为此类处理列表的问题构建解决方案,我建议您查看The Little SchemerHow to Design Programs,这两本书都将教您如何深入了解递归一般的过程。

于 2012-10-22T16:32:06.123 回答
0

如果你想计算嵌套列表的元素,你可以使用深度递归函数,正如一些人在这里回答的那样。或者我所做的是使用球拍功能(展平)使嵌套列表变平,然后在 1 级列表上使用递归,如下面的代码

  (define (howMany ls)
  (if (null? ls)
  0
  (+ 1 (howMany (cdr ( flatten ls  )))))) ; flat the nested list and deal with it as a level 1 list.
于 2014-05-02T03:37:02.140 回答