问题
I have a vector, the elements of each vector is a list, I want to sort the elements regarding to the length of list. I am using this to sort my vector but I got the error
(define vector-merge!
(lambda (newvec vec left group-size vec-size)
(let* ((top-left (min vec-size (+ left group-size)))
(right top-left)
(top-right (min vec-size (+ right group-size))))
(let mergeloop ((left left) (right right) (i left))
(cond ((and (< left top-left) (< right top-right))
(if (< (vector-ref vec left) (vector-ref vec right))
(begin
(vector-set! newvec i (vector-ref vec left))
(mergeloop (add1 left) right (add1 i)))
(begin
(vector-set! newvec i (vector-ref vec right))
(mergeloop left (add1 right) (add1 i)))))
((< left top-left)
(vector-set! newvec i (vector-ref vec left))
(mergeloop (add1 left) right (add1 i)))
((< right top-right)
(vector-set! newvec i (vector-ref vec right))
(mergeloop left (add1 right) (add1 i))))))))
(define vector-mergesort!
(lambda (orig-vec)
(let* ((vec-size (vector-length orig-vec))
(new-vec (make-vector vec-size)))
;; merge with successively larger group sizes
(do ((group-size 1 (* group-size 2)) ;; loop variables
(twice-size 2 (* twice-size 2))
(count 1 (add1 count))
(vec1 orig-vec vec2)
(vec2 new-vec vec1))
((>= group-size vec-size) ;;; exit condition
(if (even? count) ;;; copy to orig-vec, if needed
(do ((i 0 (add1 i))) ;;; this do replaces
((>= i vec-size)) ;;; vector-change!
(vector-set! orig-vec i (vector-ref new-vec i)))))
;; successively merge next two groups
(do ((left 0 (+ left twice-size))) ;; loop variables
((>= left vec-size)) ;; exit when array processed
(vector-merge! vec2 vec1 left group-size vec-size))))))
Error:
<: expects type <real number> as 1st argument, given: ((length (vector-ref route number))); other arguments were: ((length (vector-ref route number)))
回答1:
This is the expression that signals an error:
(< (vector-ref vec left) (vector-ref vec right))
The function < expects a real number as a first argument, but got a list. Since your vector vec contains lists, the expression (vector-ref vec left) returns a list (and not a number). Since you want to sort after the length of the lists, you need to write:
(< (length (vector-ref vec left)) (length (vector-ref vec right)))
in order to compare the length of the lists instead of the lists themselves.
Note: Your Scheme implementation most probably has a vector sort function in its library. In R6RS the procedure is called vector-sort!:
(vector-sort! proc vector)
where proc is a procedure used to compare two elements and vector is the vector to be sorted.
Thus, if you define:
(define (compare list1 list2)
(< (length list1) (length list2)))
you can sort it thusly
(vector-sort! compare vector)
来源:https://stackoverflow.com/questions/7858177/scheme-vector-using-merge-sorting