执行枚举过程,该过程接受值的列表并返回包含两个元素的列表的列表,其中第一个元素是值的索引,第二个元素是值本身。
(define decrease-list
(lambda (l)
((lambda (s) (s s l cons))
(lambda (s l col)
;; limitcase1: ()
(if (null? l)
(col '() '())
;; limitcase2: (a1)
(if (null? (cdr l))
(col l '())
(let ((a1 (car l)) (a2 (cadr l)))
;; limitcase3: (a1 a2)
(if (null? (cddr l))
(if (>= a2 a1)
(col l '())
(col (list a1) (list (cdr l))))
;; most usual case: (a1 a2 ...)
(s s (cdr l)
(lambda (g l*)
(if (>= a2 a1)
(col (cons a1 g) l*)
(col (list a1) (cons g l*)))))))))))))
1 ]=> (decrease-list '(1 2 3 4 1 2 3 4 1 1 1 2 1 1 0 4 3 2 1))
;Value: ((1 2 3 4) (1 2 3 4) (1 1 1 2) (1 1) (0 4) (3) (2) (1))
我没有对此发表评论,如果您有任何问题可以问,但是我认为您也可以研究我自己为您编写的代码。还请注意,可以不加考虑循环极限情况
()
和(a1)
,只检查一次这些情况:
(define decrease-list (lambda (l) ;; limitcase1: () (if (null? l) '() ;; limitcase2: (a1) (if (null? (cdr l)) (list l) ((lambda (s) (s s l cons)) (lambda (s l col) (let ((a1 (car l)) (a2 (cadr l))) ;; limitcase3: (a1 a2) (if (null? (cddr l)) (if (>= a2 a1) (col l '()) (col (list a1) (list (cdr l)))) ;; most usual case: (a1 a2 ...) (s s (cdr l) (lambda (g l*) (if (>= a2 a1) (col (cons a1 g) l*) (col (list a1) (cons g l*)))))))))))))
cond
子句中没有测试表达式; if
及其子句周围有太多括号。也许最重要的问题是代码正在尝试建立一个非递减列表,该列表将被cons
转换为(nondecreaselist (cdr s))
的结果,但是当非递减序列的长度超过一个数字时,它将开始再次回到(cdr s)
,在输入列表中又过早了。整理操作码
(null? (cadr s))
(当(cdr s)
为'()
时,cadr
无法在s
上工作),可以在代码尝试输入(null? (cdr s))
之前测试(cadr s)
。但是最好是改变这种逻辑。当输入列表包含一个元素时,仅返回包含输入列表的列表:((null? (cdr s)) (list s))
。代替(and (not (> ;...
,可以通过测试>
并执行适当的操作来使逻辑更清晰。在这种情况下,当(> (car s) (cadr s))
应该启动一个新的子列表,然后将cons
放入从nondecreaselist
返回的结果的子列表中。
否则,应将(car s)
添加到从nondecreaselist
返回的结果中的第一个子列表中。为此,我们需要通过以下方式构造返回列表:cons
将s
放入第一个子列表,然后cons
将新的子列表放回子列表的列表cdr
,这是从中返回的结果nondecreaselist
。
这里是一些修改后的代码:
(define (nondecreaselist s)
(cond ((null? s) '())
((null? (cdr s)) (list s))
((> (car s) (cadr s))
(cons (list (car s))
(nondecreaselist (cdr s))))
(else
(let ((next (nondecreaselist (cdr s))))
(cons (cons (car s)
(car next))
(cdr next))))))
使用助手功能
cons
累加的非递减列表转换为对其余列表进行运算得到的结果输入。如果辅助函数lst
的输入ndl-helper
为空,则应返回包含累积的非递减列表sublst
的列表。请注意,sublst
由于其构造方式而需要在返回之前反转,如下所述。
如果累加器sublst
为空,或者输入列表中的下一个数字大于或等于sublst
中的最大数字,则应将下一个数字简单地添加到[ C0]。通过将数字sublst
放在cons
的前面,只需检查sublst
的car
,因为它始终是sublst
中的最大值(或等于最大值)。但是,由于sublst
的顺序相反,因此需要先将其反转,然后再将其添加到不断增长的列表中。
否则,sublst
不为空,并且lst
不为空,并且输入列表中的下一个数字小于sublst
中的最大数字。因此,需要启动一个新的子列表,因此将旧的sublst
反转并通过使用空累加器sublst
调用其余cons
上的辅助函数,将lst
移至剩余计算的结果上:
sublst
两个功能均起作用:
(define (nondecreaselist-2 lst)
(define (ndl-helper lst sublst)
(cond ((null? lst) (list (reverse sublst)))
((or (null? sublst)
(>= (car lst) (car sublst)))
(ndl-helper (cdr lst) (cons (car lst) sublst)))
(else
(cons (reverse sublst) (ndl-helper lst '())))))
(ndl-helper lst '()))