两个具有相同长度和不同长度的输入列表的行为不同(Scheme)

时间:2014-05-15 14:29:44

标签: list scheme cons

代码“tsFunc”获取两个列表作为输入,它将配对两个列表中的每个元素。 它适用于大多数情况。 但是当我给出2个相等长度的列表(例如'(1 2)'(3 4)....或'(abc)'(1 2 3)....时,我发现有点奇怪的行为....奇怪的是,首先,这是代码。

[问题1]

(define (tsFunc lst1 lst2)
 (define (helper ls1 ls2 rst)  
  (reverse (if (or (null? ls1) (null? ls2))                          
      rst                                                   
      (helper (cdr ls1) (cdr ls2)               
                (cons (cons (car ls1) (car ls2)) rst)))))
(helper lst1 lst2 '()))

这样的行为:

1)列表长度不均匀的正确行为:        (tsFunc'(1 2 3)'(a b))====>输出:((1.a)(2 .b))

2)奇怪的行为,甚至长度的列表   :(tsFunc'(1 2 3)'(a b c))===>输出(错误):((3.c)(2.b)(1.a))                                ===>预期:((1.a)(2.b)(3.c))

当两个输入列表长度相同时,发生了什么? tsFunc逻辑在具有相同长度的输入列表与具有不同长度的输入列表之间具有不同的行为吗? (注意。据我所知,代码需要为最终结果“反向”。所以这不是因为代码中的“反向”)

[问题2],结果为tsFunc => tsFunc结果:(1.2)(3.4)=>尝试实现这样的产品(1 * 2)+(3 * 4)= 14,所以我喜欢这个..

(define (func l1 l2)
 (tsFunc (l1 l2)                              ;; line 2 - how to call tsFunc's result??
  (foldl (lambda (acc pair)                   ;; line 3
       (+ acc (* (car pair) (cdr pair))))     ;; line 4
     '()
     l1 l2)))                                 ;; like this?? or ??

第3,4行ok ..这是逻辑怎么做,然后,如何调用tsFunc结果将其用作输入和..最后一行的两个列表..不清楚..

2 个答案:

答案 0 :(得分:3)

第一个问题是你在每次迭代时都要反转列表,如果你真的需要反转输出,最后只做一次:

(define (tsFunc lst1 lst2)
  (define (helper ls1 ls2 rst)
    (if (or (null? ls1) (null? ls2))
        (reverse rst)
        (helper (cdr ls1) (cdr ls2)
                (cons (cons (car ls1) (car ls2)) rst))))
  (helper lst1 lst2 '()))

现在,对于第二个问题 - 代码甚至无法编译:您没有正确调用tsFunc过程,而是在错误的位置调用它。累加器参数的初始值也是错误的 - 如果要返回一个数字,则不能使用列表

(define (func l1 l2)
  (foldl (lambda (acc pair)
           (+ acc (* (car pair) (cdr pair))))
         0
         (tsFunc l1 l2)))

使用问题中的示例输入,以下是它的工作原理:

(func '(1 3) '(2 4))
=> 14

在上面的tsFunc中,我需要'(1 3)'(2 4)作为输入,将它们转换为'((1 . 2) (3 . 4)),然后foldl执行操作(1*2)+(3*4) = 14,如预期的那样。

答案 1 :(得分:0)

由于您被允许使用更高阶的功能,为什么不仅使用SRFI-1 List library fold

#!r6rs

(import (rnrs base)
        (only (srfi :1) fold)) ;; srfi-1 fold stop at the shortest list 

(define (func lst1 lst2)
  (fold (lambda (x y acc)
          (+ acc (* x y)))
        0
        lst1
        lst2))


(func '(1 3) '(2 4 8)) ; ==> 14