2016-08-31 6 views
-1

Ich könnte folgenden Code verwalten, um Elemente in einer Liste mit 2 anderen Listen zu ersetzen. Orilist und newlist haben ursprüngliche und neue Begriffe in der Reihenfolge. Der Ersatz wird mit orilist getan und newlist- wenn orilist Artikel in slist sind, wird verändert slist neue Objekte aus newlist haben entsprechen:Funktionelle Programmierung für 3 Listen in Racket

(define (list-replace-from-lists slist orilist newlist) 
    (define replaced #f) 
    (define outl '()) 
    (for ((item slist)) 
    (set! replaced #f) 
    (for ((ori_ orilist) (i (in-naturals)) #:when (equal? item ori_)) 
     (set! outl (cons (list-ref newlist i) outl)) 
     (set! replaced #t)) 
    (when (not replaced) 
     (set! outl (cons item outl)))) 
    (reverse outl)) 

2 und 5 bis 12 und 15, die jeweils in (Liste zu ersetzen, 1 2 3 4 5 6):

(list-replace-from-lists (list 1 2 3 4 5 6) (list 2 5) (list 12 15)) 

Ausgang ist:

'(1 12 3 4 15 6) 

obigen Code jedoch nicht funktionsfähig sieht und hat viele Satz! Aussagen. Wie kann dies in funktionalen Code umgewandelt werden? Sollte ich Strukturen oder andere Datentypen für diesen Zweck verwenden?

Bearbeiten: Elemente können in der ursprünglichen Liste, z. (list 1 2 3 4 5 2 6)

Antwort

2

Sie können weiterhin Listen verwenden und alles funktionsfähig halten. :-) Hier ist meine Lösung:

(define (replace-all haystack needles new-needles) 
    (define replace-alist (map cons needles new-needles)) 
    (define (replace-one item) 
    (cond ((assoc item replace-alist) => cdr) 
      (else item))) 
    (map replace-one haystack)) 

Erklärung des Codes:

  1. Zuerst bauen wir einen Ersatz Assoziationsliste (alist). Dies ist eine Liste von Paaren, deren Schlüssel der needles entsprechen und die Werte entsprechen new-needles.

  2. Dann definieren wir eine replace-one Funktion, die ein Element nimmt und sieht, ob es mit einem der Schlüssel in der Alist übereinstimmt. Wenn ja, geben wir den entsprechenden Wert zurück; Andernfalls geben wir den ursprünglichen Artikel zurück.

  3. Schließlich ordnen wir die haystack durch replace-one zu. Yay Funktionen höherer Ordnung!

Beachten Sie, dass dieser Code O(m*n) ist, wo m ist die Größe der haystack und n ist die Größe der needles, die die gleiche Laufzeit wie Ihre Version. Wenn needles groß ist, sollten Sie eine Hashtabelle anstelle eines Alist verwenden, wodurch sich die Laufzeit der Funktion auf O(m) amortisiert.

+0

Ihre Lösung funktioniert nicht, wenn ein Element später im Heuhaufen erneut auftritt, z. (ersetzen (Liste 1 2 3 4 5 2 6) (Liste 2 5) (Liste 12 15)). Die zweite 2 wird nicht ersetzt. – rnso

+0

@rnso Es funktionierte für das von Ihnen gepostete Beispiel. –

+0

Ich habe ein einfaches Beispiel veröffentlicht und Ihre Lösung ist wirklich elegant dafür. Aber wiederkehrende Artikel sind nicht ausgeschlossen. – rnso

2

Dies ist eine funktionale Lösung, die Hash verwendet, um die Verknüpfungen beizubehalten. Das macht diese Lösung O (Heuhaufenlänge Nadellänge), da unveränderliche Hashes mit Bäumen implementiert werden.

(define (list-replace-all haystack needles new-values) 
    ;; make a dictionary of elements to be replaced 
    (define hash 
    (foldl (λ (needle new-value hash) 
      (hash-set hash needle new-value)) 
      #hash() 
      needles 
      new-values)) 
    ;; do the replace. If not in hash the actual key is default 
    (map (λ (e) (hash-ref hash e e)) haystack)) 

(list-replace-all '(1 2 3 4 5 6) '(2 5) '(12 15)) 
; ==> (1 12 3 4 15 6) 
+0

Verwenden Sie 'for/hash' dafür lieber' '(für/hash ((Nadel (In-Liste Nadeln)) (Neuwert (In-Liste Neu-Werte))) (Werte Nadel Neuwert))'). Ansonsten, ausgezeichnete Antwort. +1 –

+0

Ich bin froh, dass meine Frage erzieherische Antworten hervorgebracht hat. Ich weiß nicht, warum diese Frage abgelehnt wurde. – rnso

+0

@ ChrisJester-Young Ja, es sieht klarer aus. Warum benutzt du 'in-list'? Beide sind bereits eine Liste und jedes Element wird berührt. @mso Wahrscheinlich, da es funktioniert. es ist mehr eine [Code-Rezension] (http://codereview.stackexchange.com/) Frage. – Sylwester

Verwandte Themen