我正在尝试创建一个函数,bubble,它接受一个(listof Num)并在1次冒泡排序后返回列表。以下是我的代码。
(define (check-numbers-size a b)
(cond
[(empty? b) (cons a b)]
[(> a (list-ref b 0)) (append (list-ref b 0) (append a (rest b)))]
[else (cons a b)]))
(define (bubble L)
(foldr (lambda (x y) (check-numbers-size x y)) '() L))
(bubble (list 5 2 4 7 1))
当我尝试运行它时,它会给我以下错误
append: expects a list, given 7
但是我认为b是一个列表,因为我指定了一个空列表作为此泡泡函数的基础。我做错了什么? 谢谢你的帮助。
答案 0 :(得分:1)
函数append
需要两个列表作为输入。
> (append (list 1 2 3) (list 4 5))
(list 1 2 3 4 5)
函数list-ref
从列表中提取一个元素:
> (list-ref (list 10 11 12 13 14) 2)
12
在您的代码中,您有以下表达式:
(append (list-ref b 0) ...)
这里的问题是(list-rf b 0)
返回的元素不是列表。
要从元素和列表构造新列表,您需要使用列表构造函数cons
。
(cons (list-ref b 0) ...)
请注意,表达式
中存在类似问题(append a ...)
答案 1 :(得分:1)
你是对的b
恰好是这里的一个列表。但append
的其他参数如a
或(list-ref b 0)
呢?
如果你在你的函数上放置签名,显示它们作为参数的内容以及它们返回的内容,则更容易思考这些内容。你说bubble
需要一个(Listof Num)并在1次冒泡排序后返回列表。为什么不在代码中写下来呢?
;; bubble : (Listof Num) -> (Listof Num)
;; returns the list after 1 pass of bubble sort
(define (bubble L)
...)
您应该为辅助函数check-numbers-size
执行相同的操作。你说b
是一个清单:
;; check-numbers-size : ??? (Listof Num) -> ???
由于你在正文中使用了(cons a b)
,我猜你的意思是a
为Num
,以便函数返回(Listof Num)
。
;; check-numbers-size : Num (Listof Num) -> (Listof Num)
(define (check-numbers-size a b)
...)
现在我们知道a
是Num
而b
是(Listof Num)
,我们可以弄清楚append
的参数是什么。有两个append
次调用可能是问题的原因:
(append a (rest b))
(append (list-ref b 0) (append a (rest b)))
(1)好吗?如果a
为Num
且b
为(Listof Num)
,则(1)会尝试在append
和{Num
上调用(Listof Num)
{1}}。这是问题的第一个参数a
,而不是b
。看起来您打算使用cons
代替。
(2)好吗?如果b
是(Listof Num)
,那么(list-ref b 0)
将是Num
。所以看起来(2)试图在append
和Num
上调用(Listof Num)
。就像(1)一样,它是问题的第一个论点。而且,看起来您打算使用cons
代替。
cons
函数具有签名X (Listof X) -> (Listof X)
,其中X
可以是Num
之类的任何类型。如果您想在列表中添加单个号码时使用cons
而不是append
,那么您的代码就会达到预期效果:
;; check-numbers-size : Num (Listof Num) -> (Listof Num)
(define (check-numbers-size a b)
(cond
[(empty? b) (cons a b)]
[(> a (list-ref b 0)) (cons (list-ref b 0) (cons a (rest b)))]
[else (cons a b)]))