我正在尝试定义一个以列表作为参数的函数,并返回一个布尔值(#t或#f),指示列表是否按升序排序。函数的输出应该是这样的:
(sorted? '(1 2 3 4 5)) ; => #t
(sorted? '(1 2 5 6 4)) ; => #f
(sorted? '("frank" "adam" "eve")) ; => #f
(sorted? '("adam" "eve" "frank")) ; => #t
这是我尝试解决方案:
(define (sorted? lst)
(cond
[(< (length lst) 2]
[(<= (car lst) (cadr lst)) (sorted? (cdr lst))]
[(string? lst) (string<=? (car lst) (cadr lst)) (sorted? (cdr lst))]
[else #f]))
我不断收到关于字符串部分的错误,而我似乎无法弄清楚我做错了什么。我收到错误是因为我在同一个定义中有两种不同的类型吗?我只是假设,如果列表中的参数不符合条件,它就是条件语句,应该忽略它。我是新手,我需要帮助。如果您知道我做错了什么以及我需要做些什么来解决这个问题,请分享您的知识。感谢。
答案 0 :(得分:1)
通常你不想混合数字和词汇排序,但想象一下你可以比较任何值:
(define (any<? a b)
(cond ((and (number? a) (number? b)) (< a b))
((and (string? a) (string? b)) (string<? a b))
;; You can add types here. As a default we cast it
;; to string and compare it as string
;; NB! format is Racket specific
(else (string<? (format "~A" a) (format "~A" b)))))
所以让我们排序:
(define unsorted '(#\a 5 "hello" 9 (a c b) 10 (a b c) "50"))
;; NB: sort is racket specific, R6RS has list-sort
;; with the arguments in reverse order.
(define sorted (sort test any<?))
test2 ; ==> ((a b c) (a c b) 5 "50" 9 10 #\a "hello")
;; Using a named let with the current element
;; makes you only check null? once for each pair
(define (sorted? lst <)
(or (null? lst)
(let loop ((e (car lst)) (lst (cdr lst)))
(or (null? lst)
(and (not (< (car lst) e))
(loop (car lst) (cdr lst)))))))
(sorted? unsorted any<?) ; ==> #f
(sorted? sorted any<?) ; ==> #t
如果您知道列表中元素的类型,则不会使用any<?
但该数据的具体比较过程。例如。
(sorted? '("a" "b" "cd") string<?) ; ==> #t
(sorted? '(4 7 3 5 9 3 4 6) <) ; ==> #f
答案 1 :(得分:0)
Scheme或Racket中没有适用于所有类型的通用<
。
您可以从如何定义Racket sort
功能中获取提示。它不仅需要list?
个参数。它还需要一个less-than?
参数,它是一个函数(any/c any/c . -> . any/c)
,可以是<
或string<?
或任何适合列表中事物类型的参数。
您的sorted?
函数可以执行相同的操作 - 获取列表以及less-than?
参数。
答案 2 :(得分:0)
正如其他人所说,您需要进行一次测试/比较&#39;比较你打算排序的任何函数。鉴于:
(define (sorted? test< list)
(or (null? list)
(null? (cdr list))
(and (test< (car list) (cadr list))
(sorted? test< (cdr list))))
这种功能看起来更好&#39;当您利用and
和or
获取布尔结果时。
> (sorted? < '(0 1 2 3 0))
#f
> (sorted? < '(0 1 2 3 4))
#t
> (sorted? string<? '("a" "b" "c" "a"))
#f
> (sorted? char<? '(#\a #\b #\a))
#f
>