1

在我参加的练习考试中,有一个问题要求创建一个过程,该过程接受一个列表并创建一个新列表,其中包含旧列表中每个元素的两个,同时保留顺序。他们提供的例子:

    (double-duplicate (list 1 2 3 4 4 5))

生产

    (1 1 2 2 3 3 4 4 4 4 5 5)

我设法找到了一个使用 map 和 flatten 的解决方案:

    (define (flatten list)
       (cond ((null? list) '())
             ((list? (car list)) (append (flatten (car list)) (flatten (cdr list))))
             (else (cons (car list) (flatten (cdr list))))))

    (define (double-duplicate ls)
      (define (helper list1 list2)
        (flatten (map list list1 list2)))
      (helper ls ls))

虽然它确实有效,但我认为它不是最有效的解决方案,因为我使用的是带有 3 个参数的映射形式,而且我不喜欢为了摆脱而不得不编写第二个程序(展平)的想法多余的括号。谁能想到更好的方法来做到这一点?我对如何写它有点迷茫。我很欣赏任何想法。

*注意:我正在为所有这些使用 MIT 方案。

4

2 回答 2

2

这个更适合accumulate

(define (double-duplicate lst)
  (accumulate (lambda (e acc)
                (cons e (cons e acc)))
              '()
              lst))

同样,假设它accumulate的定义与您之前的问题一样 - 即向右折叠。

于 2012-11-18T18:28:16.590 回答
1

你在用球拍吗?如果是这样,您可以使用append-map

(define (double-duplicate lst)
  (append-map (lambda (x) (list x x)) lst))

append-map类似于 Scala 的flatmap.

append-map如果需要,编写自己的版本并不难:

(define (append-map func lst)
  (fold-right (lambda (e r)
                (append (func e) r)) '() lst))
于 2012-11-18T18:27:18.970 回答