根据球拍中的指定功能对任何类型的列表进行排序

时间:2016-11-18 04:37:45

标签: functional-programming scheme racket typed-racket

我正在尝试创建一个函数,根据指定的函数对给定列表进行排序,到目前为止我有以下代码:

(: partition1 (All (A) ((A A -> Boolean) (Listof A) -> (Pr (Listof A) (Listof A)))))
(define (partition1 f x)
  (match x
    ('() (Pr '() '()))
    ((cons hd '()) (Pr (list hd) '()))
    ((cons hd tl)
     (match
         (partition1 f tl)
       ((Pr A B)
        (if (f hd (first tl))
            (Pr (cons hd A) B)
            (Pr A (cons hd B))))))))

(: quicksort1 (All (A) ((A A -> Boolean) (Listof A) -> (Listof A))))
;; sort the items according to the given order and with the quicksort algorithm
(define (quicksort1 f x)
  (match x
    ('() '())
    ((cons hd tl)
     (match (partition1 f tl)
       ((Pr A B)
        (append
         (quicksort1 A)
         (list hd)
         (quicksort1 B)))))))

我的目标是创建一个像这样的目标:

> (quicksort string<? (list "a" "g" "h" "q" "w" "z" "x" "m" "n" "p"))
==> (list "a" "g" "h" "m" "n" "p" "q" "w" "x" "z")

但是,上面的函数一直给我以下错误:

match: no matching clause for '("p")

我试图尽我所能消除这个错误,但是徒劳无功。我正在家里自己学习编程,并且会喜欢任何和所有的帮助!谢谢!

1 个答案:

答案 0 :(得分:0)

问题在于您的分区功能。

它应该只使用一个参数的函数,并且您使用该函数将列表元素分类为它们为真的那些元素和它为假的元素。

这是无类型Racket的工作版本 它应该很容易修改。

首先,分区 请注意,单例列表不是特殊情况。

(define (partition left? ls)
  (match ls
    ('() (cons '() '()))
    ((cons hd tl)
     (match
         (partition left? tl)
       ((cons l r)
        (if (left? hd)
            (cons (cons hd l) r)
            (cons l (cons hd r))))))))

如果我们使用列表的头部作为枢轴元素,排序可能如下所示:

(define (quicksort compare ls)
  (match ls
    ('() '())
    ((cons hd tl)
     (match (partition (lambda (x) (compare x hd)) tl)
       ((cons l r)
        (append
         (quicksort compare l)
         (list hd)
         (quicksort compare r)))))))


> (quicksort < '(3 4 5 2 1 7 6))
'(1 2 3 4 5 6 7)
> (quicksort string<? '("a" "g" "h" "q" "w" "z" "x" "m" "n" "p"))
'("a" "g" "h" "m" "n" "p" "q" "w" "x" "z")
> (quicksort string>? '("a" "g" "h" "q" "w" "z" "x" "m" "n" "p"))
'("z" "x" "w" "q" "p" "n" "m" "h" "g" "a")