数字分区而不使用连续的整数

时间:2017-08-18 15:06:36

标签: algorithm numbers scheme decomposition

我正在关注cs61a 2015春季课程。

计划项目中的一个问题是:

实现list-partitions过程,列出了所有方法 在不使用连续整数的情况下对正整数进行分区。该 必须按降序列出每个分区的内容。 提示:定义辅助程序以构造分区。内置追加 procedure创建一个包含两个参数列表的所有元素的列表。 questions.scm中的cons-all过程为列表列表中的每个列表添加了第一个元素。

数字5有4个不包含连续整数的分区:

5

4,1

3,1,1

1,1,1,1,1

由于连续,因此不包括以下5个分区 整数:

3,2

2,2,1

2,1,1,1

我找到了一个解决方案但无法理解

;; List all ways to partition TOTAL without using consecutive numbers.
(define (apply-to-all proc items)
  (if (null? items)
      '() 
      (cons (proc (car items))
            (apply-to-all proc (cdr items)))))

(define (cons-all first rests)
  (apply-to-all (lambda (rest) (cons first rest)) rests))

(define (caar x) (car (car x)))
(define (cadr x) (car (cdr x)))
(define (cddr x) (cdr (cdr x)))
(define (cadar x) (car (cdr (car x))))
(define (cdar x) (cdr (car x)))

(define (partitions-r a b)
  (if (= a 0) nil
    (append (cons-all a (list-partitions b))
            (cons-f (partitions-r (- a 1) (+ b 1))
    ))
  ))

(define (cons-f lst)
  (cond 
        ((eq? lst nil) nil)
        ((eq? (cdar lst) nil) lst)

        ((< (caar lst) (cadar lst)) (cons-f (cdr lst)))
        ((= (caar lst) (+ 1 (cadar lst))) (cons-f (cdr lst)))
        (else (cons (car lst) (cons-f (cdr lst))))
))

(define (list-partitions total)
  (cond ((= total 1) '((1)) )
        ((= total 0) '(()) )
        (else (append nil (partitions-r total 0)))
))

; For these two tests, any permutation of the right answer will be accepted.
(list-partitions 5)
; expect ((5) (4 1) (3 1 1) (1 1 1 1 1))
(list-partitions 7)
; expect ((7) (6 1) (5 2) (5 1 1) (4 1 1 1) (3 3 1) (3 1 1 1 1) (1 1 1 1 1 1 1))

功能分区-r和cons-f有什么作用?非常感谢你!

1 个答案:

答案 0 :(得分:0)

不知道Scheme,但伪代码中的递归生成可能如下所示:

function Partitions(N, LastValue, list):
if N = 0 
   print list
else
    for i from  Min(LastValue, N) downto  1
        if (i != LastValue - 1)    //reject consecutive number
            Partitions(N - i, i, list  + [i]);