0

有人可以告诉我这段代码中的错误吗?我不熟悉递归,所以我真的不明白下面的代码有什么问题。

(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,则为 '()

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

我的想法正确吗?如果没有,我错在哪里??预先感谢!

4

2 回答 2

2

一方面,结果应该是一个字符串;在你的基地,它不是。

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

于 2013-11-06T17:05:42.363 回答
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-joinmap并且format

(define (counting lst)
  (string-join 
   (map (lambda (s) (format "~a, ~a" (car s) (length (cdr s)))) lst)
   "\n"))
于 2013-11-06T17:06:25.330 回答