2014-02-17 3 views
1

В СХЕМЕСортировка списка подсписков в схеме

Я пытаюсь написать часть кода для сортировки списка подсписков, используя разницу между элементами каждого подсписка. Что я имею в виду:

т.е.

список подсписков:. '(' (Ted 10 4) '(Barbie 10 5)' (автомобиль 10 7) «(шар 10 6))

и я хочу, чтобы отсортировать список на основе разницы между 2-й и 3-й элемент каждого списка подсписок таким образом отсортированный список должен выглядеть в порядке возрастания (низшего к высшему):

«(» (автомобиль 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) (если (null? curr) (curr) (если (> (diff (доступ-aquprice (машина toylist)) (доступ-продажа цена (машина toylist))) (дифференциал (доступ-aquprice (CADR toylist)) (доступа SalePrice (CADR toylist)))) ("привет") "до свидания") ) ) ' – 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)))))) 

(take и drop определены в 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

Смежные вопросы