Scheme:返回第一个奇数的向量函数

时间:2017-02-08 07:37:07

标签: racket

我无法弄清楚如何编写一个返回列表中第一个奇数的向量函数。

Ex :( check-expect(first-oddnumb 2 3 4 5 6)3));;它返回3,因为3是列表中的第一个奇数。

1 个答案:

答案 0 :(得分:0)

  

我无法弄清楚如何编写一个返回列表中第一个奇数的向量函数。

我的困惑与@ Sylwester的相同:“矢量函数”?问题的其余部分似乎很有意义。

我可以帮你写一个函数,它返回列表中的第一个奇数。

我们希望该功能像这样工作

(first-odd-number 2 3 4 5 6) ;; => 3

所以我们要做的第一件事就是学习如何编写一个接受可变数量参数的函数

(define (variadic . xs) xs)

(variadic 1 2)     ;; => '(1 2)
(variadic 1 2 3)   ;; => '(1 2 3)
(variadic 1 2 3 4) ;; => '(1 2 3 4)
(variadic)         ;; => '()

请注意.参数前的xs。这为我们提供了一种方法,可以将所有传递的参数收集到绑定标识符xs中。注意如何将参数收集到列表中。还要注意xs如何仍然是一个列表(空列表'()),即使函数调用中没有给出参数。

现在我们可以开始编写你的函数了

(define (first-odd-number . xs)
  ;; so we know xs will be a list here ...
  )

让我们谈谈xs

的可能状态
  • xs可能是空的,在这种情况下我们应该返回什么?也许是0或其他什么? (稍后会详细介绍)

否则,xs至少有一个号码......

  • 是第一个数字是一个奇数?如果是,请返回该号码
  • 是第一个偶数的数字?如果是,请返回first-odd-number
  • 中剩余数字的xs

好的,我们几乎可以在Racket verbatim

中定义它
(define (first-odd-number . xs)
  ;; begin case analysis of xs
  (cond
    ;; is the list of numbers empty? return 0
    [(empty? xs) 0]
    ;; the list is not empty, continue ...
    ;; is the first number odd?
    [(odd? (car xs)) (car xs)]
    ;; otherwise...
    ;; the number even, check remaining numbers
    [else (apply first-odd-number (cdr xs))]))

(first-odd-number 2 3 4 5 6) ;; => 3
(first-odd-number 3 4 5 6)   ;; => 3
(first-odd-number 4 5 6)     ;; => 5
(first-odd-number)           ;; => 0

这就是它!

<强>改进...

如果你像我一样,0让你感到不安。如果您只获得甚至号码列表怎么办?返回值应该是什么?

(first-odd-number 2 4 6) ;; => 0

这有点奇怪。我们可以使用0来表示没有找到奇数,但也许有更好的方法......

(struct Just (value) #:transparent)
(struct None () #:transparent)

(define (first-odd-number . xs)
  (cond
    ;; no odd number was found; return None
    [(empty? xs) (None)]
    ;; an odd number was found, return (Just n)
    [(odd? (car xs)) (Just (car xs))]
    ;; otherwise check the remaining numbers
    [else (apply first-odd-number (cdr xs))]))

(first-odd-number 2 3 4 5 6) ;; => (Just 3)
(first-odd-number 3 4 5 6)   ;; => (Just 3)
(first-odd-number 4 5 6)     ;; => (Just 5)
(first-odd-number)           ;; => (None)

现在,当first-odd-number的来电者使用该功能时,我们无需记住0是我们需要考虑的特殊情况

(define (print-the-first-odd-number . xs)
  (match (apply first-odd-number xs)
    [(Just x) (printf "the number is ~a\n" x)]
    [(None) (printf "no odd number was found\n")]))

(print-the-first-odd-number 2 3 4 5 6) ;; the number is 3
(print-the-first-odd-number 2 4 6)     ;; no odd number was found