我试图从列表中删除最后一次出现的值,并且在嵌套列表的递归调用期间我的程序失败。使用Scheme,如何在递归调用(嵌套列表)期间保持变量的值?
我有一个统计符号的出现次数的函数:
(define (countOccurrences lst elem count)
(cond
[(empty? lst) count]
[(list? (car lst)) (countOccurrences (cdr lst) elem
(countOccurrences (car lst) elem count))]
[(equal? (car lst) elem) (countOccurrences (cdr lst) elem (add1 count))]
[else (countOccurrences (cdr lst) elem count)]))
和主体是在这里:
(define (lastLess lst elem)
(let ((count (countOccurrences lst elem 0)))
(if (< 0 count)
(lastLessHelper lst elem count)
lst)))
辅助功能:
(define (lastLessHelper lst elem count)
(cond
[(empty? lst) empty]
[(eq? count 0) (cdr lst)]
[(eq? (car lst) elem) (set! count (sub1 count))
(cond
[(eq? count 0) (cdr lst)]
[else (cons (car lst)
(lastLessHelper (cdr lst) elem count))])]
[(list? (car lst)) (cons (lastLessHelper (car lst) elem count)
(lastLessHelper (cdr lst) elem count))]
[else (cons (car lst) (lastLessHelper (cdr lst) elem count))]))
的问题是这条线:
[(list? (car lst)) (cons (lastLessHelper (car lst) elem count) (lastLessHelper (cdr lst) elem count))]
我递减“计数”变量每当(car lst)
等于elem
,并且所述第一递归调用(lastLessHelper (car lst) elem count)
它正确地递减,但在当调用返回,并将其递归对CDR LST:(lastLessHelper (cdr lst) elem count))]
“计数的值'返回到其原始值。
它适用于普通列表的输入,如(lastLess '(1 2 3 2 4 5) '2))
我使用嵌套列表时作为输入,如(lastLess '(1 (2 3) 4 2 5) '2)
返回(1 (2 3) 4 2 5)
正确地得到(1 2 3 4 5)
,但。
如何在递归调用期间保持'count'的值?我应该注意到,可能有更简单的方法来做到这一点,但这是一项家庭作业练习,我们被禁止使用“反向”呼叫。
编辑:Sylwester的评论帮助我理解。我的问题是不计算一个项目的发生,问题是要删除最后一个项目的发生。我的想法是首先计算该项目的出现次数,然后遍历列表并递减计数直到它为0,然后我会知道删除该项目,然后仅剩下列表的其余部分cons
。
谢谢,这是有道理的,但是我还是失去了对如何递减这个计数为列表被遍历。当我使用DrRacket通过调试器时,当执行两个递归调用'[(list?(car lst))(cons(lastLessHelper(car lst))时,我可以看到count的值从'1'回到'2' )elem count)(lastLessHelper(cdr lst)elem count))]' – Al5678
@ Al5678它不是同一个变量。您递归并在下一轮中为同一个命名变量赋予一个新值。在你的例子中,你是在''car'和'cdr'的递归,因此你可以期望它是一个'pair'对吗?'而不是数字。你可以使用'+',然后它们将两者加在一起,但都使用'count',所以如果它是'2',你会在每一轮中获得比你更多的'2'。其中一个需要有'0'作为计数。或者你可以像我一样使用count来反对'car'递归并在'cdr'递归中使用结果。 – Sylwester