2016-03-21 4 views
1

Nach dem Schreiben:Sortierfunktion mit anpassbaren Vergleichsfunktion

(define (sort-asc l) 
    (cond ((eq? l '()) '()) 
     ((eq? (cdr l) '()) (list (car l))) 
     ((< (car l) (cadr l)) (cons (car l) (sort-asc (cdr l)))) 
     (else (cons (cadr l) (sort-asc (cons (car l) (cddr l))))))) 

Wie schreiben Sie eine Funktion, die zusätzlich eine Vergleichsfunktion als Parameter nehmen?

Versuchte:

(define (sort-f l f) 
    (cond ((eq? l '()) '()) 
     ((eq? (cdr l) '()) (list (car l))) 
     ((lambda()(f (car l) (cadr l))) (cons (car l) (sort-f (cdr l) f))) 
     (else (cons (cadr l) (sort-f (cons (car l) (cddr l)) f))))) 

Aber (sort-f '(4 3 8 2 5) <) gibt die gleiche Liste. p.s. Gibt es eine Möglichkeit, diesen Code eleganter aussehen zu lassen, indem man alle car 's, cadr' s und cdr 's irgendwie umschreibt?

+0

sein Ich glaube nicht Ihre 'SORT-ASC' entweder funktioniert. Sie sollten wahrscheinlich etwas wie [Insertion sort] (https://en.wikipedia.org/wiki/Insertion_sort) oder [quicksort] (https://en.wikipedia.org/wiki/Quicksort) ausprobieren. Wie auch immer, um die als Argument übergebene Funktion zu verwenden, können Sie einfach '(F ARG1 ARG2)' verwenden. Keine Notwendigkeit für diese "LAMBDA". – jkiiski

+0

@jkiiski Nicht nur "keine Notwendigkeit für das" Lambda "", sondern dass es aktiv bewirkt, dass der Code nicht funktioniert, da "Lambda" eine Prozedur zurückgibt, die immer truthy ist. –

+1

@ ChrisJester-Young Vielleicht dachte jkiiski, dass X10D '' cond ... (((lambda() (f (car l) (cadr l))))) bedeutet hätte, was funktioniert hätte. –

Antwort

2

Ihre dritte cond Verzweigungsbedingung sollte (f (car l) (cadr l)) sein, nicht (lambda() ...). Der lambda-Ausdruck gibt eine Prozedur zurück (die nicht aufgerufen wird), und da alle Prozeduren truthy sind, wird der vierte Zweig (else) nie erreicht.

Das heißt,

((lambda()(f (car l) (cadr l))) (cons (car l) (sort-f (cdr l) f))) 

sollte

((f (car l) (cadr l)) (cons (car l) (sort-f (cdr l) f))) 
+0

Ich denke '((lambda() (f (car l) (cadr l))) würde funktionieren, aber das ist eine Menge Extra-Eingabe für '(f (car l) (cadr l))', sowie viel weniger lesbar. – Vatine