6

说我有清单:(a b ((c)) (d + e) ((e + f)) (g) () h)

如何获得以下列表(最好带有函数):(a b c (d + e) (e + f) g h)

换句话说:

  • 如果嵌套列表只有一个元素,则将其简化为该元素。在上面的示例中,这((c))被简化为 c 。也((e + f))变成了(e + f)

  • 如果嵌套列表有多个元素,则它保持不变。与上面的示例(d + e)一样(d + e)

  • 如果嵌套列表为空,则将其简单地删除。

最后,我不确定扁平化一词是否适用于这种情况。我希望我的问题很清楚。如果没有,请告诉我。

提前致谢!

4

2 回答 2

5

试试这个代码:

(define (atom? x)
  (and (not (pair? x)) (not (null? x))))

(define (strip lst)
  (if (or (null? lst) (atom? lst) (not (null? (cdr lst))))
      lst
      (strip (car lst))))

(define (flatten lst)
  (cond ((or (null? lst) (atom? lst))
         lst)
        ((null? (strip (car lst)))
         (flatten (cdr lst)))
        (else
         (cons (flatten (strip (car lst))) (flatten (cdr lst))))))

使用您的示例进行测试时,它给出了预期的答案:

> (flatten '(a b ((c)) (d + e) ((e + f)) (g) () h))
> (a b c (d + e) (e + f) g h)
于 2011-10-15T18:55:15.540 回答
0

这个想法是你需要一个递归函数:

  1. 检查列表是否为空
  2. 检查第一项是否是列表,如果不是,则检查cons应用于cdr列表的函数
  3. 否则,将函数应用于carandcdrconsing 结果。

这是一个未经测试的尝试:

(define flatten
  (lambda lst
    (cond 
      ((null? lst) lst)
      ((atom? (car lst)) (cons (car lst) (flatten (cdr lst))))
      (else (cons (flatten (cons (car (car lst) (cdr (car ls))) 
                  (flatten (cdr lst)))))))

whereatom?是一个测试列表中的元素是否不是列表的函数。以下是The Little Schemeratom?中的定义:

(define atom?
  (lambda (x)
    (and (not (pair? x)) (not (null? x)))))

如果您在组织递归函数的逻辑时遇到困难,我强烈推荐 The Little Schemer。

于 2011-10-15T08:39:17.833 回答