【问题标题】:Extract every number in the list and reconstruct the list?提取列表中的每个数字并重建列表?
【发布时间】:2009-09-25 12:50:37
【问题描述】:

我需要创建这个函数flat,它应该从输入列表中重新收缩一个新列表(但在这里,输入列表可以有一个嵌套列表):

例如。 (A (B (C) D) A) 的平面是 (A B C D A)

我的算法如下,不知道对不对:

  1. 检查列表是否为空:如果不是,继续;如果是,则完成——返回空列表
  2. 如果列表长度为 1,则完成 -- 返回列表
  3. 如果列表的长度大于 1,我现在该怎么办? (我可以使用carcdr 来提取列表,但是在任何一种情况下,我怎样才能使它递归地提取列表到最后,我正在考虑使用append 来重新构建列表。)

任何帮助/提示将不胜感激。

【问题讨论】:

  • 如果列表的长度为 1,它仍可能看起来像 ((1)),因此必须是 flat-tened

标签: list scheme


【解决方案1】:

提示是,如果列表不是null?,则不应关注传递给flat的列表长度,而是检查列表的car是否为一个列表本身或只是一个原子。如果它是一个列表本身,您想要展平它,以及展平列表的cdr

编辑:好吧,考虑一下在两种不同情况下会发生什么,一种使用cons,另一种使用append

(append '(a b c) '(d e f)) => (a b c d e f)

(cons '(a b c) '(d e f)) => '((a b c) d e f)

在第一种情况下,您会得到一个平面列表,而在第二种情况下,您不会得到一个平面列表。你可以试试

(define (bad-flatten lst) 
  (if ((null? lst) 
      '()
      (append (car (flatten lst)) (cdr (flatten lst)))))

但如果lst 中的car 不是 列表,它将不起作用。您需要第三种情况,使用cond,如下所示:

(define (incomplete-flatten lst)
  (cond ((null? lst) 
         '())
        ((list? (car lst)) 
         (append (flatten (car lst)) (flatten (cdr lst))))
        (else 
         ;; you need to do something different here. I can
         ;; think of at least two options.
        )))

【讨论】:

  • 是的,我该怎么做?扁平化列表?请提供更多帮助。我知道我需要把它弄平。但是怎么做?
  • 好的,检查它是否是一个列表。我使用附加吗?或缺点?如果是缺点,我一次只能添加 2 个。所以添加汽车,然后再次递归调用该函数。
【解决方案2】:

可能不是最优化的解决方案。也许您可以进一步改进它:

(define (list-flatten lst)
  (if (not (null? lst))
      (let loop ((args lst) (ret (list)) (c null))
         (if (not (null? args))
           (begin
             (set! c (car args))
             (cond ((list? c) (loop (cdr args) (append ret (list-flatten c)) c))
             (else (loop (cdr args) (append ret (list c)) c))))
           ret))
       #f))

【讨论】:

  • 我想起了 LISP 是多么的丑陋……我希望谈论 LISP 感觉很好,但可惜我太喜欢它了。
猜你喜欢
  • 1970-01-01
  • 2022-11-30
  • 2020-08-20
  • 1970-01-01
  • 2022-10-02
  • 2017-12-15
  • 2020-06-22
  • 2017-08-29
  • 1970-01-01
相关资源
最近更新 更多