我正在尝试学习计划(扩大思维而不是作业),而且与程序语言相比,我仍在努力解决其差异。
请考虑以下事项:
在过程语言术语中,我有两个基于零的整数数组a和b,长度分别为n> = 1和n + 1,并且想要输出长度为n + 1的数组c,其中:
c [0] = b [0] + a [0]; c [n] = b [n] + a [n-1]; c [i] = b [i] + Max(a [i-1],a [i])(1< = i< = n-1)
所以,例如,如果a = [5,6,1]且b = [1,2,3,4],那么c = [6,8,9,5]
我只能用程序语言来做这件事。例如在Pascal中:
function MaxAdd(a, b : array; n : integer) : array;
var
i : integer;
begin
c[0] = b[0] + a[0];
c[n] = b[n] + a[n-1];
for i = 1 to n-1 do
c[i] = b[i] + Max(a[i-1],a[i]);
result := c;
end;
我正在尝试使用我使用两个整数列表而不是数组的方案。以下作品,但对我来说似乎很笨拙。有没有更简洁的方法来处理终结案件?
(define (max a b)
(if (> a b) a b))
(define (maxaddhelper l1 l2)
(cond
((= 1 (length l1)) (list (+ (car l1) (car l2))))
(else (cons
(+ (max (car l1) (car (cdr l1))) (car l2))
(maxaddhelper (cdr l1) (cdr l2)) ))))
(define (maxadd l1 l2)
(cond
((= 1 (length l1)) (list (+ (car l1) (car l2)) (+ (car l1) (car (cdr l2)))))
(else
(cons (+ (car l1) (car l2))
(maxaddhelper l1 (cdr l2)) ))))
测试输出......
Welcome to DrRacket, version 5.93 [3m].
Language: scheme; memory limit: 128 MB.
> (maxadd (list 5 6 1) (list 1 2 3 4))
(6 8 9 5)
>
答案 0 :(得分:2)
此问题会大量使用索引,因此更适合于方案vector
- 它提供与数组相同的基于索引的高效操作。例如,Racket中的惯用解决方案是:
(define (max-add a b)
(let* ([n (vector-length a)]
[c (make-vector (add1 n))])
(vector-set! c 0 (+ (vector-ref b 0)
(vector-ref a 0)))
(vector-set! c n (+ (vector-ref b n)
(vector-ref a (sub1 n))))
(for ([i (in-range 1 n)])
(vector-set! c i (+ (vector-ref b i)
(max (vector-ref a (sub1 i))
(vector-ref a i)))))
c))
(max-add '#(5 6 1) '#(1 2 3 4))
=> '#(6 8 9 5)
没有人说Scheme中的所有问题都必须使用链表来解决,这个例子特别表明有时你必须选择更适合这项工作的数据结构。如果列表是必需的,那么list->vector
和vector->list
将允许您在数据结构之间来回切换。
修改强>
正如@uselpa所提到的,也可以仅使用列表解决这个问题,更多的是SICP的精神和Scheme的惯用语。为了完整起见,这是我的实现,比其他答案更简单,更容易理解:
(define (max-add a b)
(let loop ([a a] [b b] [prev (car a)])
(if (null? a)
(list (+ (car b) prev))
(cons (+ (car b) (max prev (car a)))
(loop (cdr a) (cdr b) (car a))))))
(max-add '(5 6 1) '(1 2 3 4))
=> '(6 8 9 5)
答案 1 :(得分:1)
FWIW,这是一个在纯方案中实现的基于列表的解决方案:
(define (maxadd lst1 lst2)
(let loop ((last (car lst1)) (lst1 lst1) (lst2 lst2))
(if (null? lst2)
'()
(let ((ca1 (car lst1)) (cd1 (cdr lst1)))
(cons (+ (max last ca1) (car lst2))
(loop ca1 (if (null? cd1) lst1 cd1) (cdr lst2)))))))
然后
> (maxadd '(5 6 1) '(1 2 3 4))
'(6 8 9 5)