Kadane的方案算法(球拍)

时间:2016-11-25 21:07:00

标签: algorithm scheme racket kadanes-algorithm

我理解Kadane的算法(数组中所有连续子数组的最大总和)如何在“伪代码”中工作的逻辑,我确信我可以将它作为C或C ++中的函数实现。但是,我正在尝试使用Scheme(Racket;文件扩展名为.rkt)中的列表来实现它,我没有经验。

我正在寻找的最终结果是......

Input: (maxsum `(1 4 -2 1))
Output: 5

到目前为止,我已经开发了两个可以在maxsum函数中使用的辅助函数。

(1)size:返回列表中元素的数量。

(define size
   (lambda (list)
      (cond
         [(not (list? list)) 0]
         [(null? list) 0]
         [else (+ 1 (size (cdr list)))]
      )
   )
)

(2)sum:返回列表中所有元素的总和。

(define sum
   (lambda (list)
      (cond
         [(not (list? list)) 0]
         [(null? list) 0]
         [else (+ (car list) (sum (cdr list)))]
      )
   )
)

我如何定义/设计maxsum函数?

2 个答案:

答案 0 :(得分:0)

这是Phyton code on wikipedia之后的图案版本:

(define (maxsum lst)
  (define (aux lst max-ending-here max-so-far)
    (if (null? lst)
        max-so-far
        (let ((new-max-ending-here (max 0 (+ (car lst) max-ending-here))))
          (aux (cdr lst) new-max-ending-here (max max-so-far new-max-ending-here)))))
  (aux lst 0 0))

(maxsum '(1 4 -2 1))   ; => 5

(maxsum '(-2 1 -3 4 -1 2 1 -5 4))  ; => 6

它是尾递归的,因此它将被编译成一个有效的迭代程序。

答案 1 :(得分:0)

[Python code] [1]几乎直译为Racket:

(define (max_subarray A)
  (define-values (max_ending_here max_so_far) (values 0 0))
  (for ((x (in-list A)))
    (set! max_ending_here (max 0 (+ max_ending_here x)))
    (set! max_so_far (max max_so_far max_ending_here)))
  max_so_far)

测试:

(max_subarray  `(1 4 -2 1))
(max_subarray  '(-2 1 -3 4 -1 2 1 -5 4))

输出:

5
6

请注意,递归函数通常优先于Racket中的迭代函数并使用" set!"在这里气馁。

以下使用更高级别的功能applymap来执行不同的步骤:

(define (maxsum lst)
  (define subarrays
    (for*/list ((start (length lst))
                (len (range 1 (- (add1(length lst)) start))))
      (take (drop lst start) len)))
  (define sumlist (map (λ (x) (apply + x)) subarrays))
  (apply max sumlist))

以下是更详细的表格:

(define (maxsum lst)
  (define subarrays
    (for*/list ((start (length lst))
                (len (range 1 (- (add1(length lst)) start))))
      (take (drop lst start) len)))
  (displayln "\n----- SUBARRAYS ---------")
  (displayln subarrays)
  (define sumlist (map (λ (x) (apply + x)) subarrays))
  (displayln "----- SUMS OF SUBARRAYS ---------")
  (displayln sumlist)
  (display "MAX SUM:")
  (apply max sumlist))

测试:

(maxsum  `(1 4 -2 1))
(maxsum  '(-2 1 -3 4 -1 2 1 -5 4))

输出:

----- SUBARRAYS ---------
((1) (1 4) (1 4 -2) (1 4 -2 1) (4) (4 -2) (4 -2 1) (-2) (-2 1) (1))
----- SUMS OF SUBARRAYS ---------
(1 5 3 4 4 2 3 -2 -1 1)
MAX SUM:5

----- SUBARRAYS ---------
((-2) (-2 1) (-2 1 -3) (-2 1 -3 4) (-2 1 -3 4 -1) (-2 1 -3 4 -1 2) (-2 1 -3 4 -1 2 1) (-2 1 -3 4 -1 2 1 -5) (-2 1 -3 4 -1 2 1 -5 4) (1) (1 -3) (1 -3 4) (1 -3 4 -1) (1 -3 4 -1 2) (1 -3 4 -1 2 1) (1 -3 4 -1 2 1 -5) (1 -3 4 -1 2 1 -5 4) (-3) (-3 4) (-3 4 -1) (-3 4 -1 2) (-3 4 -1 2 1) (-3 4 -1 2 1 -5) (-3 4 -1 2 1 -5 4) (4) (4 -1) (4 -1 2) (4 -1 2 1) (4 -1 2 1 -5) (4 -1 2 1 -5 4) (-1) (-1 2) (-1 2 1) (-1 2 1 -5) (-1 2 1 -5 4) (2) (2 1) (2 1 -5) (2 1 -5 4) (1) (1 -5) (1 -5 4) (-5) (-5 4) (4))
----- SUMS OF SUBARRAYS ---------
(-2 -1 -4 0 -1 1 2 -3 1 1 -2 2 1 3 4 -1 3 -3 1 0 2 3 -2 2 4 3 5 6 1 5 -1 1 2 -3 1 2 3 -2 2 1 -4 0 -5 -1 4)
MAX SUM:6