我正在尝试制作一个程序,该程序确定输入的列表是否用符号替代。例如,如果给出以下列表,则我的程序将返回true:[-1、5,-10]或[5,-17、25]。如果给出以下列表,则程序将返回false:[-1,-5、6]或[1,-2,-6]。
我尝试过做一个简单的cond语句,该语句检查列表中第一个数字的符号,然后在检查列表中的第二个数字以确保第一个数字为正,第二个数字为负或第一个数字是负数,第二个数字是正数。
(define (alternating-signs-in-list? lst)
(cond
[(> (first lst) 0)
(cond [(< (first (rest lst)) 0) (alternating-signs-in-list? (rest lst))])]
[(< (first lst) 0)
(cond [(> (first (rest lst)) 0) (alternating-signs-in-list? (rest lst))])]
[else false]))
我希望所提供的代码能够正常工作,但遇到错误,指出:
first:需要一个非空列表;给定:空
我进行以下检查时发生了此错误:
(check-expect (alternating-signs-in-list? (cons 1 (cons -5 (cons 50 empty)))) true).
为什么会发生以下错误,我是否可以通过简单的方法使代码开始工作。谢谢。
答案 0 :(得分:2)
技巧是同时比较成对的元素(列表的第一和第二个),直到列表用完为止。您收到的错误是因为您忘记处理空列表的情况,尤其是对于此问题,当列表仅剩一个元素时,我们还需要处理这种情况。
在继续之前,实现same-sign?
过程非常有用,如果我们利用sgn
过程(返回数字的 sign ),并且假设0
是肯定的:
(define (same-sign? n1 n2)
; they have the same sign if their `sgn` value is the same
(= (if (zero? n1) 1 (sgn n1))
(if (zero? n2) 1 (sgn n2))))
主要过程如下:
(define (alternating-signs-in-list? lst)
(cond ((or (empty? lst) (empty? (rest lst))) #t) ; empty list / single element case
((same-sign? (first lst) (second lst)) #f) ; they are NOT alternating
(else (alternating-signs-in-list? (rest lst))))) ; advance recursion
或者,我们也可以只使用布尔连接器来编写上面的代码:
(define (alternating-signs-in-list? lst)
(or (empty? lst)
(empty? (rest lst))
(and (not (same-sign? (first lst) (second lst)))
(alternating-signs-in-list? (rest lst)))))
无论哪种方式,它都能按预期工作:
(alternating-signs-in-list? '(-1 5 -10))
=> #t
(alternating-signs-in-list? '(5 -17 25))
=> #t
(alternating-signs-in-list? '(-1 -5 6))
=> #f
(alternating-signs-in-list? '(1 -2 -6))
=> #f