4

我正在尝试制作一个迭代过程来比较列表中的每个奇数和每个偶数元素。每个奇数应该是奇数,每个偶数应该是偶数。第一个数字必须是奇数。输出应该是这样的:

(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

我试图将两个元素与 this: 进行比较(and (odd? (car lst)) (even? (cadr lst)),但我不知道如何继续(cddr lst)

4

5 回答 5

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在尾部位置使用带有递归调用的 an,因此它是迭代的 - 它类似于您考虑解决方案的方式。这是另一个解决方案,它更明确地表明这确实是一个迭代过程:

(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?))))))
于 2013-06-15T19:08:08.230 回答
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))
于 2013-06-15T19:16:38.517 回答
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)))
于 2013-06-17T20:41:12.797 回答
0

为什么不将一般情况设计为高阶函数并实现奇偶呢?作为特例?这样你也可以实现奇偶?,或平方? - 棕褐色?,或素数? - carmicheal?很容易。

(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)))))
于 2013-06-17T14:05:18.630 回答
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))))))
于 2013-06-16T05:32:39.863 回答