【问题标题】:Getting same parity for a list of numbers为数字列表获取相同的奇偶校验
【发布时间】:2021-05-24 21:12:13
【问题描述】:

我正在做基于第一个参数的奇数/偶数过滤列表的 SICP 练习。例如:

(same-parity 1 2 3 4 5 6 7)
; parity of first argument '1' is odd
; and we apply the 'odd' filter to the remaining list, (2 3 4 5 6 7)
(1  3 5 7)

这是我想出的,但我遇到了一些麻烦:

; Helper function
(define (list-append lst elem)
  (if (null? lst)
      (cons elem nil)
      (cons (car lst) (list-append (cdr lst) elem))))

; Actual function
(define (same-parity first . lst)
  ; start with an empty list, and we'll build it with side-effects
  (define L '())
    (define (same-parity-inner remaining-lst)
      ; when the list is exhausted, just return L
      (cond ((null? remaining-lst) L)
            ; if the current element of the list has the same parity
            ; as the first element, add that to our list
            (else (if (= (modulo first 2) (modulo (car remaining-lst) 2))
                      (list-append L (car remaining-lst)))
                    ; and then recurse with the remaining list elements
                   (same-parity-inner (cdr remaining-lst)))))
    (same-parity-inner lst))

现在我知道关于 SICP 问题有很多很好的解决方案,但我想知道是否有人可以指出我的实施的愚蠢之处,并帮助我找出更好的方法。


更新,这是一个实现,它不是很好,但它是我拥有的第一个工作版本。我发现必须使用“实际列表”而不是 vargs 函数参数有点棘手,所以我编写了另一个内部函数来接受实际列表(也许有更好的方法来做到这一点?)。

; Helper
(define (append-list lst1 lst2)
  (if (null? lst1)
      lst2
      (cons (car lst1) (append (cdr lst1) lst2))))


(define (same-par first . lst)
  (define (same-par-inner lst)
    (cond ((null? lst) '())
          ((= (modulo first 2) (modulo (car lst) 2)) (append-list (list (car lst)) (same-par-inner (cdr lst)) ))
          (else (same-par-inner (cdr lst)))))
  (same-par-inner lst))

(same-par 1 2 3 4 5 6 7 99 11)
; (3 5 7 99 11)

有没有办法在不定义内部函数的情况下递归地做到这一点?

【问题讨论】:

    标签: scheme lisp sicp


    【解决方案1】:

    您可以使用apply 进行递归调用,而无需使用辅助函数。它的最后一个参数是一个列表,它将在函数调用中传播到参数中。这允许您再次传递first 以及(cdr lst)

    您也可以只使用cons 从一个元素和一个后续列表构建一个新列表,而不是创建一个临时列表来使用append-list

    (define (same-par first . lst)
      (cond ((null? lst) '())
            ((= (modulo first 2) (modulo (car lst) 2))
             (cons (car lst)
                   (apply same-par first (cdr lst)) ))
            (else (apply same-par first (cdr lst)))))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-29
      • 2015-04-04
      • 2013-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多