写一个奇数的Scheme过程和



编写一个Scheme过程,接受一个列表并返回列表中奇数的和。例如,(sumodd '(1(2() 6) 3(5) 2))返回9

这是我的代码

(define (sumodd ls)
(cond ((null? ls) 0)
((list? (car ls)) (sumodd (car ls)))
((= (modulo (car ls) 2) 1)) (+ (car ls) (sumodd (cdr ls)))
(else (sumodd (cdr ls)))))

我尽力了,但还是答不出正确的答案。

在第二项中,检查列表的car是否为列表。如。((5) 3 1)。当你对(5)列表求和时,(3 1)会发生什么?逻辑不应该是把sumodd的结果加在carcdr上吗?

您的代码,重新格式化为清晰,

(define (sumodd ls)
(cond
((null? ls)
#| case1: |#   0                  )
((list? (car ls))
#| case2: |#   (sumodd (car ls))  )
((= (modulo (car ls) 2) 
1)
#| case3: |#    #| no code |#     )
(+
#| case4: |#   (car ls)
(sumodd (cdr ls))  )
(else
#| else: |#    (sumodd (cdr ls))  )  ))

正如你所看到的,除了在另一个答案中提到的case2中的问题,你真的应该将(cdr ls)sumodd添加到你拥有的(car ls)sumodd中,case3中还有错误括号的问题,导致它分裂成两个错误的案例,3和4。

但实际上,由于列表不是奇数,另一个有效的选择是将lscdr中的数字进行sumodd,而不是像您所拥有的car

回到错误的情况,第一个,case3,说总是只返回#t,如果lscar是奇数。

第二个case4,测试+是否为假值。如果事实并非如此,那么这个案子,一旦开庭,就会开庭。但是它不会调用+函数,因为+已经作为被测试的值发挥了作用。该子句的主体由两个表达式组成。第一个被忽略,第二个被求值并返回它的值。

这一切都是错误的。更正后的代码可能是

(define (sum-odd-numbers ls)
(cond 
((null? ls)               0)
((list? (car ls))         (sumodd (cdr ls)))    ; cdr, not car
; or do the other thing and add cdr and car
((= (modulo (car ls) 2) 
1)
(+ (car ls) (sumodd (cdr ls))) )
(else                     (sumodd (cdr ls))  )))

我也重命名了函数。命名很重要。

(define sum-odd
(lambda (l)
(fold-right (lambda (x a)
(if (list? x)
(+ a (sum-odd x))
(if (odd? x)
(+ a x)
a)))
0
l)))

最新更新