2014-02-17 50 views
1

在方案排序子列表的列表方案

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

即子列表的

列表:'('(TED 10 4) '(芭比10 5)'(轿厢10 7)“(球10 6))

,我想根据每个子列表列表的第二和第三个元素之间的差异列表进行排序从而排序列表看起来应该像升序(低到高):

“(”(汽车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"))) 
+0

您可以使用内置的'sort'过程,还是应该从头开始实现它? –

+1

我必须从头开始 – user3259073

+0

而我需要创建一个新的排序列表。到目前为止我所拥有的是: '(define(sortlist curr) (if(null?curr)(curr) (if(>(diff(access-aquprice(car toylist))(access-saleprice(car ()) ) ) – user3259073

回答

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)) 
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))

干杯!
Andres