有一点帮助,伙计们。 你如何按照一定的模式的一个例子将被分拣R,W,B的列表进行排序列表,其中R是第一位的,然后W,则B.喜欢的东西(sortf '(WRWBRWBB))
至(RRWWWBBB)
任何答案是极大的赞赏。
有一点帮助,伙计们。 你如何按照一定的模式的一个例子将被分拣R,W,B的列表进行排序列表,其中R是第一位的,然后W,则B.喜欢的东西(sortf '(WRWBRWBB))
至(RRWWWBBB)
任何答案是极大的赞赏。
这是一个功能版本荷兰国旗问题 。 下面是我的两分钱-使用sort
议事O(n log n)
复杂性:
(define sortf
(let ((map '#hash((R . 0) (W . 1) (B . 2))))
(lambda (lst)
(sort lst
(lambda (x y) (<= (hash-ref map x) (hash-ref map y)))))))
使用filter
与O(4n)
的复杂性:
(define (sortf lst)
(append (filter (lambda (x) (eq? x 'R)) lst)
(filter (lambda (x) (eq? x 'W)) lst)
(filter (lambda (x) (eq? x 'B)) lst)))
使用partition
与O(3n)
复杂::
(define (sortf lst)
(let-values (((reds others)
(partition (lambda (x) (eq? x 'R)) lst)))
(let-values (((whites blues)
(partition (lambda (x) (eq? x 'W)) others)))
(append reds whites blues))))
上述解决方案都写在一个函数式编程风格,创建与回答有新的名单。 最佳O(n)
可以如果我们表示输入作为载体,其允许通过引用索引元件来构造单通势在必行溶液。 事实上,这是问题的原配方如何旨在解决:
(define (swap! vec i j)
(let ((tmp (vector-ref vec i)))
(vector-set! vec i (vector-ref vec j))
(vector-set! vec j tmp)))
(define (sortf vec)
(let loop ([i 0]
[p 0]
[k (sub1 (vector-length vec))])
(cond [(> i k) vec]
[(eq? (vector-ref vec i) 'R)
(swap! vec i p)
(loop (add1 i) (add1 p) k)]
[(eq? (vector-ref vec i) 'B)
(swap! vec i k)
(loop i p (sub1 k))]
[else (loop (add1 i) p k)])))
要知道,以前的解决方案变异就地输入向量。 这是相当优雅,并且按预期工作:
(sortf (vector 'W 'R 'W 'B 'R 'W 'B 'B 'R))
=> '#(R R R W W W B B B)
这是不使用溶液sort
或高阶函数。 (即没有乐趣可言),这并没有真正的排序,但它解决您的问题,而无需使用排序。 named let
和case
都在该解决方案中最奇特的形式。
除非它需要的不是那种用我不会做像这样。 我认为lepple的答案是既优雅又容易理解。
该解决方案是O(n)
因此它比其他人有非常多的球可能更快。
#!r6rs
(import (rnrs base))
(define (sort-flag lst)
;; count iterates over lst and counts Rs, Ws, and Bs
(let count ((lst lst) (rs 0) (ws 0) (bs 0))
(if (null? lst)
;; When counting is done build makes a list of
;; Rs, Ws, and Bs using the frequency of the elements
;; The building is done in reverse making the loop a tail call
(let build ((symbols '(B W R))
(cnts (list bs ws rs))
(tail '()))
(if (null? symbols)
tail ;; result is done
(let ((element (car symbols)))
(let build-element ((cnt (car cnts))
(tail tail))
(if (= cnt 0)
(build (cdr symbols)
(cdr cnts)
tail)
(build-element (- cnt 1)
(cons element tail)))))))
(case (car lst)
((R) (count (cdr lst) (+ 1 rs) ws bs))
((W) (count (cdr lst) rs (+ 1 ws) bs))
((B) (count (cdr lst) rs ws (+ 1 bs)))))))
请查找如
(define sort-lookup '((R . 1)(W . 2)(B . 3)))
(define (sort-proc a b)
(< (cdr (assq a sort-lookup))
(cdr (assq b sort-lookup))))
(list-sort sort-proc '(W R W B R W B B))
可运行R6RS(IronScheme)这里的解决方案: http://eval.ironscheme.net/?id=110
你只需要使用内置的排序或排序,你已经拥有并使用自定义谓词。
(define (follow-order lst)
(lambda (x y)
(let loop ((inner lst))
(cond ((null? inner) #f)
((equal? x (car inner)) #t)
((equal? y (car inner)) #f)
(else (loop (cdr inner)))))))
(排序 '(WRWBRWB)(后续订单'(RWB)))
;值50:(rrwwwbb)