编写一个获取两个列表的过程 - lst,dup-count - 并根据 dup-count 复制 lst(下面的解释)

Writing a procedure which gets two lists - lst, dup-count - and duplicates lst according to dup-count (explanation below)

我需要在 Scheme 中编写一个 L3 程序 duplicate-items,它得到两个列表 - lst , dup-count - 和根据 dup-count 中相同位置定义的数字复制 lst 的每一项。 如果 dups-count 长度小于 lst,dup-count 应该被视为循环列表。

示例:

(重复项目'(1 2 3) '(1 0))→ '(1 3)

(重复项目'(1 2 3) '(2 1 0 10 2))→ '(1 1 2)

您可以假设 dup-count 包含数字并且不为空。

所以我试着递归地做:

(define (dup-it lst countList c)
  (if (empty? countList)
      lst
  (if (empty? lst)
      '()
  (if (= c 0)
      (dup-it (cdr lst) (cdr countList) (cadr lst))
  (cons (car lst) (dup-it lst countList (- c 1)))))))

(define (duplicate-items lst dupCount)
  (dup-it lst dupCount (car dupCount)))

遗憾的是,进展并不顺利:(

我的输出是:

(duplicate-items '(1 2 3) '(1 0))

>>>  '(1 2 2 3)

有什么想法吗?

如果你会使用SRFI-1列表函数,那真的很简单:

(define (duplicate-items lst dup-count)
  (concatenate! (map (lambda (item count) (make-list count item))
                     lst
                     (apply circular-list dup-count))))

有趣的一点是 circular-list,它 return 是一个根据其参数构建的循环列表(通过 applydup-count 列表中解压)。为了简单起见,无论 dup-count 的长度如何,总是这样做。只要 lst 是有限的,地图就会结束并且 return 重复元素列表的列表,然后将它们连接在一起成为一个列表。


使用 Racket 函数、理解和相同方法的替代方法:

(define (duplicate-items lst dup-count)
   (flatten (for/list ([item lst]
                       [count (in-cycle dup-count)])
                      (make-list count item))))

这段代码使用原始方案完成了工作。这个想法是,如果 dup-list 的长度小于 lst 的长度,那么它会重复附加 dup- list 使其变得比 lst 长,因此它变成“循环”。

(define (duplicate-items lst dup-count)
(let ((dupc (if (< (length dup-count) (length lst))
              (append-times dup-count (+ 1 (quotient (length lst) (length dup-count)))) ; make the length of dupc bigger than lst)
              dup-count)))
   (define (dup-items z dc res)
     (if (null? z)
         res
         (dup-items (cdr z) (cdr dc) (append (append-times (cons (car z) '()) (car dc)) res))
     )) (reverse (dup-items lst dupc '())))
)

(define (append-times items n) ; append a list n times for making dup-count have sufficient length
  (define (iter z a res) ; this proc is also used for duplicating the items in lst
    (if (= a 0)
        res
        (iter z (- a 1) (append z res))
    )
  )
  (iter items n '())
)

(define (reverse lst)
  (define (iter z result)
    (if (null? z)
        result
        (iter (cdr z) (cons (car z) result))))
  (iter lst '())
)

(define (length items)
  (if (null? items)
      0
      (+ 1 (length (cdr items))))
)

一些例子:

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

;Value: (1 2 2 3 3 3 4 5 5)

(duplicate-items (list 1 2 3 4 5) (list 1 0))

;Value: (1 3 5)