如何编写列出两个列表并返回这样的列表的方案功能



如何实现此功能

如果获得两个列表(A B C),(D E)

和返回列表(A D B D C D A E B E C E)

列表元素都是整数,结果列表的元素顺序是免费的

我尝试了

(define (addlist L1 L2)
  (define l1 (length L1))
  (define l2 (length L2))
  (let ((result '()))
     (for ((i (in-range l1)))
        (for ((j (in-range l2)))
           (append result (list (+ (list-ref L1 i) (list-ref L2 j))))))))

但是它返回错误,因为结果为'()

我不知道如何解决这个问题,请帮助我

数据转换方法:

   (a b c ...) (x y ...) 
1.  ==>  ( ((a x) (b x) (c x) ...)  ((a y) (b y) (c y) ...) ...)
2.  ==>  (  (a x) (b x) (c x) ...    (a y) (b y) (c y) ...  ...)
3.  ==>  (  (a+x) (b+x) ... )
(define (addlist L1 L2)
    (map (lambda (r) (apply + r))    ; 3. sum the pairs up
         (reduce append '()          ; 2. concatenate the lists
            (map (lambda (e2)        ; 1. pair-up the elements
                    (map (lambda (e1) 
                            (list e1 e2))  ; combine two elements with `list`
                         L1))
                 L2))))

测试(在mit-scheme中):

(addlist '(1 2 3) '(10 20))
;Value 23: (11 12 13 21 22 23)

您可以简化这个,因此没有单独的步骤#3?


我们可以在这里进一步将不同的位和零件分开,因为

(define (bind L f) (join (map f L)))
(define (join L) (reduce append '() L))
(define yield list)

然后,

(bind '(1 2 3) (lambda (x) (bind '(10 20) (lambda (y) (yield (+ x y))))))
;Value 13: (11 21 12 22 13 23)
(bind '(10 20) (lambda (x) (bind '(1 2 3) (lambda (y) (yield (+ x y))))))
;Value 14: (11 12 13 21 22 23)

您去这里:

(define (addlist L1 L2)
  (for*/list ((i (in-list L1)) (j (in-list L2)))
    (+ i j)))
> (addlist '(1 2 3) '(10 20))
'(11 21 12 22 13 23)

诀窍是使用for/list(或嵌套for s的for*/list),它将自动为您完成append。另外,请注意,您只能在列表上迭代,无需使用索引。

要获得结果"相反",倒置L1和L2:

(define (addlist L1 L2)
  (for*/list ((i (in-list L2)) (j (in-list L1)))
    (+ i j)))
> (addlist '(1 2 3) '(10 20))
'(11 12 13 21 22 23)

在方案中,不建议使用诸如集合的函数!或附加!因为它会导致数据更改或可变,而不是funcitonal编程样式。

应该这样:

(定义(添加列表val lst)  (if(null?lst)'()    (cons(list val(car lst))(附加列表val(cdr lst))))))))))(定义(添加列表LST0 LST1)  (if(null?lst0)'()    (附录(ADD-ONE-LIST(CAR LST0)LST1)            (添加列表(CDR LST0)LST1)))))))

首先理解函数添加列表,它递归地自称为自身,每次构建LST的Val和拳头元素到列表中,并将其作为最终答案。

添加列表函数就像添加列表一样。

(define (addlist L1 L2)
 (flatmap (lambda (x) (map (lambda (y) (+ x y)) L1)) L2))
(define (flatmap f L)
 (if (null? L)
     '()
     (append (f (car L)) (flatmap f (cdr L))))) 
1 ]=> (addlist '(1 2 3) '(10 20))
;Value 2: (11 12 13 21 22 23)

与威尔和园林一起进行。如果您要使用方案,则可能会使用惯用方案。

用来构建列表对我来说有点奇怪。(列表的综合性更适合)通常用于诱导顺序副作用。那和rsr5不能定义/列表或*/列表。

flatmap是一个相当常见的功能范式,在其中您使用附录而不是弊端来构建列表以避免嵌套和空的sublists

它不起作用,因为诸如append之类的功能不会突变容器。您可以通过append!这样的突变功能来解决问题。通常功能突变为!的名称,例如set!等。

,但可以在不进行突变的情况下实现这一目标。您必须更改算法才能将结果发送到下一次迭代。这样:

(let loop ((result '()))
   (loop (append result '(1)))

如您所见,循环会被调用时,结果将为:

'()
'(1)
'(1 1)
'(1 1 1)
....

遵循此逻辑,您应该能够更改算法以使用此方法而不是for循环。您必须传递更多参数才能知道何时必须退出并返回result

我将在今天晚些时候尝试添加一个更完整的答案。

这是append!的实现:

(define (append! lst1 lst2)
  (if (null? (cdr lst1))
    (set-cdr! lst1 lst2)
    (append! (cdr lst1) lst2)))

最新更新