对方案中的子列表进行排序

时间:2014-02-17 15:55:08

标签: list sorting loops recursion scheme

IN SCHEME

我正在尝试编写一段代码来对子列表列表进行排序,使用每个子列表的元素之间的差异。我的意思是:

即,

子列表清单:'('(ted 10 4)'(芭比10 5)'(车10 7)'(球10 6))

我希望根据每个子列表列表的第2和第3个元素之间的差异对列表进行排序,因此排序列表应该按升序排列(从最低到最高):

'('(car 10 7)'(球10 6)'(芭比10 5)'(泰迪10 4))

我为子列表创建了访问器:

(define (access-name x) (car x))
(define (access-aquprice x)(cadr x))
(define (access-saleprice x)(caddr x))

排序循环令我困惑,请帮忙! :)

到目前为止我只有:

(define (sortlist curr) 
  (if (null? curr)
      (curr) 
      (if (> 
           (diff (access-aquprice (car toylist))  (access-saleprice (car toylist))) 
           (diff (access-aquprice (cadr toylist)) (access-saleprice (cadr toylist))))
          ("hello") 
          "goodbye")))

2 个答案:

答案 0 :(得分:1)

免责声明:这是我自己写的第一种。它可能没有错误

所以你首先必须写一个基本的排序。我建议你看一下this page并选一个。我之所以选择Merge sort,因为维基百科插图很好,并且很容易递归地实现它。

我们将从排序简单列表开始。

所以,首先是合并:

(define (merge lst1 lst2)
  (cond 
    ((null? lst1) lst2)
    ((null? lst2) lst1)
    ((> (car lst1) (car lst2)) 
     (cons (car lst2) (merge lst1 (cdr lst2))))
    (else
     (cons (car lst1) (merge (cdr lst1) lst2)))))

然后合并排序:

(define (merge-sort lst)
  (define len (length lst))
  (if (<= len 1)
      lst
      (let ((n (quotient len 2)))
        (merge (merge-sort (take lst n)) (merge-sort (drop lst n))))))

takedrop SRFI-1 中定义(如果需要)

尝试:

> (merge-sort '(7 3 0 1 5 8))
'(0 1 3 5 7 8)
> (merge-sort '())
'()
> (merge-sort '(3 14 15 9 26 53 58 97 23))
'(3 9 14 15 23 26 53 58 97)

看起来不错。

现在我们将它扩展为使用自定义比较功能:

(define (merge-sort compare lst)

  (define (merge lst1 lst2)
    (cond 
      ((null? lst1) lst2)
      ((null? lst2) lst1)
      ((compare (car lst1) (car lst2)) 
       (cons (car lst2) (merge lst1 (cdr lst2))))
      (else
       (cons (car lst1) (merge (cdr lst1) lst2)))))

  (define (inner-sort lst)
    (define len (length lst))
    (if (<= len 1)
        lst
        (let ((n (quotient len 2)))
          (merge (inner-sort (take lst n)) (inner-sort (drop lst n))))))

  (inner-sort lst))

然后

> (merge-sort > '(7 3 0 1 5 8))
'(0 1 3 5 7 8)
> (merge-sort < '(7 3 0 1 5 8))
'(8 7 5 3 1 0)

最后,为您的案例创建自定义比较函数:

(merge-sort 
 (lambda (a b) (> (- (access-aquprice a) (access-saleprice a))
                  (- (access-aquprice b) (access-saleprice b))))
 '((ted 10 4) (barbie 10 5) (car 10 7) (ball 10 6)))

产量

'((car 10 7) (ball 10 6) (barbie 10 5) (ted 10 4))

答案 1 :(得分:0)

我知道这个问题已经过了3年,你不能使用内置的sort函数,但万一有人需要它:

(sort (lambda (x y) (< (- (cadr x) (caddr x))
                       (- (cadr y) (caddr y))))
      '((ted 10 4) (barbie 10 5) (car 10 7) (ball 10 6)))

返回((car 10 7) (ball 10 6) (barbie 10 5) (ted 10 4))

干杯!
安德烈