我正在尝试制作一个迭代程序,比较列表中的每个奇数和每个偶数元素。每个奇数应该是奇数,每个偶数应该是偶数。第一个数字必须是奇数。 输出应该是这样的:
(odd-even-args? 1 2 3 4 5) --> #t
(odd-even-args? 1 2 4 4 5) --> #f
(odd-even-args? 1 0 1) --> #t
我尝试将两个元素与此进行比较:(and (odd? (car lst)) (even? (cadr lst))
,但我不知道如何继续使用(cddr lst)
。
答案 0 :(得分:5)
这是一种可能性:遍历所有列表,询问每个元素是否满足相应的谓词(even?
或odd?
)并在谓词之间交替:
(define (odd-even-args? . lst)
(let loop ((lst lst)
(is-odd? #t))
(if (null? lst)
#t
(and ((if is-odd? odd? even?) (car lst))
(loop (cdr lst) (not is-odd?))))))
上面的答案使用and
在尾部位置进行递归调用,因此它是迭代的 - 它与您考虑解决方案的方式类似。这是另一种解决方案,它更明确地表明这确实是一个迭代过程:
(define (odd-even-args? . lst)
(let loop ((lst lst)
(is-odd? #t))
(cond ((null? lst) #t)
(((if is-odd? even? odd?) (car lst)) #f)
(else (loop (cdr lst) (not is-odd?))))))
另一个解决方案,使用布尔连接器而不是条件表达式:
(define (odd-even-args? . lst)
(let loop ((lst lst)
(is-odd? #t))
(or (null? lst)
(and ((if is-odd? odd? even?) (car lst))
(loop (cdr lst) (not is-odd?))))))
答案 1 :(得分:2)
只是另一种变体(可能不是很好......)
(define (odd-even-args? . args)
(define (iter lst)
(cond ((null? lst) #t)
((null? (cdr lst)) (odd? (car lst)))
((and (odd? (car lst)) (even? (cadr lst))) (iter (cddr lst)))
(else #f)))
(iter args))
答案 2 :(得分:0)
(define (range start end)
(if (>= start end)
nil
(cons start (range (+ start 1) end)))
(define (odd-even-args? . args)
(apply and
(map (lambda (value index)
(eqv? (even? index)
(even? value)))
args
(range 1 (+ 1 (length args))))))
答案 3 :(得分:0)
为什么不将一般情况设计为高阶函数并实现奇偶?作为一个特例?那样你还可以实现偶数?,或方形?-tan ?,或者?-comehehe?很容易。
(define (predx?-predy? predx predy)
(lambda L
(let loop ((lst L) (pred?1 predx) (pred?2 predy))
(if (null? lst)
#t
(and (pred?1 (car lst)) (loop (cdr lst) pred?2 pred?1))))))
;;flip preds each recursion
(define odd-even? (predx?-predy? odd? even?))
(define even-odd? (predx?-predy? even? odd?))
(define square-tan (predx?-predy? square? tan?))
(define prime?-Carmichael? (predx?-predy? prime? (lambda (x) (and (not (prime? x)) (fermat-prime? x)))))
答案 4 :(得分:0)
作为练习,我使用SRFI-1编写了一个版本并折叠:
(define (odd-even-args? . xs)
(first
(fold
(lambda (x data)
(let ((result (first data))
(count (second data)))
(list
(and
((if
(odd? count)
odd?
even?)
x)
result)
(+ 1 count))))
'(#t 1)
xs)))