8 Stimmen

Wie teilt man in Racket (Scheme) eine Liste in gleich große Stücke auf?

Beispiel:
Wie man die Liste umwandelt:
'(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)

In die Liste der Listen:
'((0 1 2 3) (4 5 6 7) (8 9 10 11) (12 13 14 15))

Auf der Grundlage der bisherigen Antworten habe ich mir Folgendes überlegt:

Definieren Sie zunächst eine Funktion, die bis zu 'n' Elemente vom Anfang der Liste aufnimmt:

(define (take-up-to n xs)
  (define (iter xs n taken)
    (cond
      [(or (zero? n) (empty? xs)) (reverse taken)]
      [else (iter (cdr xs) (- n 1) (cons (car xs) taken))]))
  (iter xs n '()))

Die zweite ist eine ähnliche Funktion für den Rest der Liste:

(define (drop-up-to n xs)
  (define (iter xs n taken)
    (cond
      [(or (zero? n) (empty? xs)) xs]
      [else (iter (cdr xs) (- n 1) (cons (car xs) taken))]))
  (iter xs n '()))

Das hätte man auch als eine Funktion machen können, die zwei Werte zurückgibt, und Racket hat eine Funktion 'split-at', die das gleiche Ergebnis liefert, aber ich habe das als Übung gemacht.

ps. Ist dies die korrekte Anwendung der Schwanzrekursion?

Dann kann Split-in-Chunks wie folgt geschrieben werden:

(define (split-into-chunks n xs)
  (if (null? xs)
      '()
      (let ((first-chunk (take-up-to n xs))
            (rest-of-list (drop-up-to n xs)))
        (cons first-chunk (split-into-chunks n rest-of-list)))))

pps. Kann diese noch weiter verbessert werden oder ist sie "gut genug"?

1voto

amindfv Punkte 8348

Wenn Sie solche Probleme besser lösen möchten, würde ich sehr empfehlen Der kleine Betrüger . Sie werden lernen, in Begriffen zu denken, die diese Probleme überschaubar machen, und es dauert nur ein paar Stunden, um es von vorne bis hinten durchzuarbeiten.

0voto

yanyingwang Punkte 117

Nachdem ich Racket etwas länger benutzt habe, ist mir aufgefallen, dass die zweite Verwendung von let dokumentiert in seinem offizielles Dokument wird in seiner Welt sehr häufig verwendet.

Meine Methode für diese Frage wäre also folgende:

(let loop ([lst '(1 2 3 4 5 6 7 8 9 10 1 12 13 14)]
           [result '()])
  (if (< (length lst) 3)
      (append result (list lst))
      (loop (drop lst 3)
            (append  result (list (take lst 3))))))

Der Clou dabei ist, dass Sie diesen Code in ein Format wie das folgende bringen können:

(let loop ([lst '(...)]
           [result '()])
  (if (empty? lst)
      result
      (loop (... lst ...)
            (append result (... lst ...)))))

und versuchen Sie dann, sie zu vervollständigen, wenn Sie auf ein Problem stoßen, das durch eine Schleife gelöst werden kann.

Und auch zu Ihrer Information, jemand hat dies bereits als Funktion namens slice-at . Der Implementierungscode ist zu finden unter aquí .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X