Scheme中嵌套列表的递归

时间:2013-11-06 16:56:18

标签: recursion scheme

有人可以在此代码中显示我的错误吗?我对递归并不熟悉,所以我真的不明白下面代码的错误。

(define (counting lst)  
    (if (null? lst)
        '()
        (string-append (number->string (car (car lst))) 
                       ", " 
                       (number->string (length (cdr (car lst)))) 
                       (counting (cdr lst)))))

输入:'((2 b a) (1 f e c) (0 m))

代码预期输出:"2, 2\n1, 3\n0, 1\n"

上述代码的实际输出:

string-append: contract violation
  expected: string?
  given: '()
  argument position: 4th
  other arguments...:
   "0"
   ", "
   "1"

据我了解,

基本情况:如果列表的长度嵌套= 0或null,则为'()

归纳案例:在嵌套了“,”的列表中附加第一个数字,并嵌套列表其余部分的长度。

我的想法是否正确?如果没有,我错了? 提前谢谢!

2 个答案:

答案 0 :(得分:2)

首先,结果应该是一个字符串;在您的基地,它不是。

另一方面,你永远不会添加换行符。

答案 1 :(得分:1)

你的基本情况应该返回""而不是'(),因为它用于string-append的递归调用:

(define (counting lst)  
  (if (null? lst)
      "" ; <===
      (string-append (number->string (car (car lst))) 
                     ", " 
                     (number->string (length (cdr (car lst)))) 
                     "\n" ; <===
                     (counting (cdr lst)))))

,例如

(counting '((2 b a) (1 f e c) (0 m)))
=> "2, 2\n1, 3\n0, 1\n"

修改

更优雅的解决方案是使用内置函数string-joinmapformat

(define (counting lst)
  (string-join 
   (map (lambda (s) (format "~a, ~a" (car s) (length (cdr s)))) lst)
   "\n"))