Recursion 如果列表中的所有数字都相同,那么如何在Racket中编写一个函数来生成true,否则将生成false?

Recursion 如果列表中的所有数字都相同,那么如何在Racket中编写一个函数来生成true,否则将生成false?,recursion,conditional-statements,racket,Recursion,Conditional Statements,Racket,我如何在Dr.Racket中定义一个函数,如果列表中的所有数字都相同,则生成布尔值true,否则生成布尔值false。 这是我目前的代码: (define (same-numbers? lst) (cond [(empty? (rest lst)) (first lst)] [else (equal? (first lst)(same-numbers? (rest lst)))])) 如果我输入: (same-numbers? (cons 5 (cons 5 (cons 5

我如何在Dr.Racket中定义一个函数,如果列表中的所有数字都相同,则生成布尔值true,否则生成布尔值false。 这是我目前的代码:

(define (same-numbers? lst)
  (cond
    [(empty? (rest lst)) (first lst)]
    [else (equal? (first lst)(same-numbers? (rest lst)))]))
如果我输入:

(same-numbers? (cons 5 (cons 5 (cons 5 empty))))
> (same-numbers? (cons 5 (cons 5 (cons 5 empty))))
#true

我期望的输出是正确的。然而,相反,我得到了一个错误的答案。我该怎么纠正呢?

正如评论所指出的,假设列表只包含数字,最简单的方法是执行
(apply=lst)
。如果您想通过显式递归从头开始实现这一点,我建议使用另一种方法:如果列表中有多个元素,则将第一个元素作为引用,并将所有其他元素与之进行比较,如下所示:

(define (same-numbers? lst)
  (if (or (empty? lst) (empty? (rest lst))) ; trivial cases
      #t
      (let loop ((val (first lst)) ; take first element as reference
                 (lst (rest lst))) ; loop over the other elements
        (or (empty? lst)           ; base case: we're finished
            (and (equal? (first lst) val)   ; base case: stop if elements are different
                 (loop val (rest lst))))))) ; recursive case: keep iterating
它适用于我的测试用例:

(same-numbers? '())
=> #t
(same-numbers? '(5))
=> #t
(same-numbers? '(5 5))
=> #t
(same-numbers? '(5 5 5))
=> #t

(same-numbers? '(5 1))
=> #f
(same-numbers? '(1 5))
=> #f
(same-numbers? '(1 5 5))
=> #f
(same-numbers? '(5 5 1))
=> #f

就像Atharva Shukla的评论
(apply=lst)
一样好

但是
(apply='())
将显示错误

#lang Racket
(define lon (list 1/2 1/2 1/2 1/3))
(define lon2 (list 1/2 1/2 1/2 0.5))

(define (same-n? lon)
  (andmap (lambda (n) (= (first lon) n)) lon))

;;; TEST

(same-n? lon) ; #f
(same-n? lon2) ; #t
(same-n? '()) ; #t

我将从迄今为止您的代码开始,并找出其中的问题:

(define (same-numbers? lst)
  (cond
    [(empty? (rest lst)) (first lst)]
    [else (equal? (first lst)(same-numbers? (rest lst)))]))
我看到的第一个问题是基本情况:如果
lst
是一个数字列表,那么
(first lst)
将是一个数字,而不是您想要的布尔值

;; same-numbers? : [Listof Number] -> Boolean
要解决此问题,基本情况应返回
#true

(define (same-numbers? lst)
  (cond
    [(empty? (rest lst)) #true]
    [else (equal? (first lst) (same-numbers? (rest lst)))]))
我看到的下一个问题是递归情况:因为
相同的数字?
返回一个布尔值,所以不应该使用
equal?
就好像您需要一个数字一样。在第一个
和第二个
之间使用
equal?

(define (same-numbers? lst)
  (cond
    [(empty? (rest lst)) #true]
    [else ... (equal? (first lst) (second lst)) ... (same-numbers? (rest lst)) ...]))
现在,
s周围需要填充一些东西,将“前两个相等”和“其余相同数字”中的信息结合起来。当前两个相等,其余的相同时,它们都相等,因此用
填充
..
s以组合它们:

(define (same-numbers? lst)
  (cond
    [(empty? (rest lst)) #true]
    [else (and (equal? (first lst) (second lst)) (same-numbers? (rest lst)))]))
如果我输入:

(same-numbers? (cons 5 (cons 5 (cons 5 empty))))
> (same-numbers? (cons 5 (cons 5 (cons 5 empty))))
#true
还有一个问题:空列表。因此,只需为其添加另一个
cond
案例:

;; same-numbers? : [Listof Number] -> Boolean
(define (same-numbers? lst)
  (cond
    [(empty? lst)        #true]
    [(empty? (rest lst)) #true]
    [else (and (equal? (first lst) (second lst)) (same-numbers? (rest lst)))]))
使用它:

> (same-numbers? empty)
#true
> (same-numbers? (cons 5 empty))
#true
> (same-numbers? (cons 5 (cons 5 (cons 5 empty))))
#true
> (same-numbers? (cons 5 (cons 5 (cons 6 empty))))
#false
您只需使用
(apply=lst)
(相同的数字?(列表5))
返回
#f
<代码>(相同的数字?(列表5))
返回
#t
<代码>(相同的数字?(列表5))
返回
5
<代码>(相同的号码?(列表))
出错。递归函数定义要做的第一件事是注意它在所有情况下总是返回相同类型的结果。