(方案)如何将2个不同大小的列表一起添加

时间:2014-09-09 20:05:52

标签: scheme

我对计划完全陌生,我在尝试添加两个不同大小的列表时遇到了麻烦。我想知道如何正确地添加2个不同大小的列表。在我的代码中,我比较了值并将'(0)附加到较短的列表,以便它们可以获得相同的大小,但即使这样做,我也不能使用map来添加2个列表。运行程序后,我收到错误代码。我得到的结果是'(2 4 5 4)。任何人都可以帮我吗?感谢。

#lang racket

(define (add lst1 lst2)

(cond [(< (length lst1) (length lst2)) (cons (append lst1 '(0)))]  
    [else lst1])

(cond 
    ((and (null? lst1)(null? lst2)) null) 
(else
    (map  + lst1 lst2))))

;;Result should be '(2 4 6 4)
(add '(1 2 3) '(1 2 3 4))

错误:

cons: arity mismatch;
the expected number of arguments does not match the given number
expected: 2
given: 1
arguments...:
'(1 2 3 0)

4 个答案:

答案 0 :(得分:1)

你的代码的问题是有两个cond表达式一个接一个 - 两者都将执行,但只会返回第二个的结果 - 换句话说,代码没有按照你的想法去做。现在,为了解决这个问题,如果我们将解决方案分成两部分(一般来说,这是一个好策略!),它会更容易。试试这个:

(define (fill-zeroes lst n)
  (append lst (make-list (abs n) 0)))

(define (add lst1 lst2)
  (let ((diff (- (length lst1) (length lst2))))
    (cond [(< diff 0)
           (map + (fill-zeroes lst1 diff) lst2)]
          [(> diff 0)
           (map + lst1 (fill-zeroes lst2 diff))]
          [else (map + lst1 lst2)])))

说明:

  • fill-zeroes过程负责填充具有给定数量的零的列表尾部
  • add程序负责确定需要填写的列表,以及当两个列表都具有正确的大小执行实际添加时

对于列表长度的任何组合,它都可以正常工作:

(add '(1 2 3 4) '(1 2 3))
=> '(2 4 6 4)
(add '(1 2 3) '(1 2 3 4))
=> '(2 4 6 4)
(add '(1 2 3 0) '(1 2 3 4))
=> '(2 4 6 4)

答案 1 :(得分:1)

与Oscar相似,略短:

(define (fill0 lst len)
  (append lst (make-list (- len (length lst)) 0)))

(define (add lst1 lst2)
  (let ((maxlen (max (length lst1) (length lst2))))
    (map + (fill0 lst1 maxlen) (fill0 lst2 maxlen))))

或者,为了好玩,反过来说:

(define (add lst1 lst2)
  (let ((minlen (min (length lst1) (length lst2))))
    (append 
     (map + (take lst1 minlen) (take lst2 minlen))
     (drop lst1 minlen)
     (drop lst2 minlen))))

答案 2 :(得分:1)

无需预先计算列表的长度,并将零添加到列表中的一个或另一个的末尾。在这里,我们通过简单的递归来解决问题:

(define (add xs ys)
  (cond ((and (pair? xs) (pair? ys))
          (cons (+ (car xs) (car ys)) (add (cdr xs) (cdr ys))))
        ((pair? xs) (cons (car xs) (add (cdr xs) ys)))
        ((pair? ys) (cons (car ys) (add xs (cdr ys))))
        (else '())))

这适用于所有奥斯卡的测试:

> (add '(1 2 3 4) '(1 2 3))
(2 4 6 4)
> (add '(1 2 3) '(1 2 3 4))
(2 4 6 4)
> (add '(1 2 3 0) '(1 2 3 4))
(2 4 6 4)

如果您愿意,可以使用named-let编写,并获得相同的结果:

(define (add xs ys)
  (let loop ((xs xs) (ys ys) (zs '()))
    (cond ((and (pair? xs) (pair? ys))
            (loop (cdr xs) (cdr ys) (cons (+ (car xs) (car ys)) zs)))
          ((pair? xs) (loop (cdr xs) ys (cons (car xs) zs)))
          ((pair? ys) (loop xs (cdr ys) (cons (car ys) zs)))
          (else (reverse zs)))))

玩得开心!

答案 3 :(得分:1)

更简单的版本。

(define (add x y)
  (cond ((and (pair? x) (pair? y))
         (cons (+ (car x) (car y))
               (add (cdr x) (cdr y))))
        ((pair? x) x)
        (else y)))