Ich habe diesen Typ Mat a = [[a]]
, um eine Matrix in Haskell darzustellen. Ich muss eine Funktion schreiben, die eine Matrix dreht, zum Beispiel wird [[1,2,3],[0,4,5]
, [0,0,6]]
zu [[3,5,6],[2,4,0],[1,0,0]]
, also habe ich Folgendes gemacht:
rotateLeft :: Mat a->Mat a
rotateLeft [[]] = []
rotateLeft (h:t) = (map last (h:t)):(rotateLeft (map init (h:t)))
Aber die Ausgabe ist
[[3,5,6],[2,4,0],[1,0,0],[*** Exception: Prelude.last: empty list
Ich weiß nicht, was ich in den Basisfall setzen soll, um diese Ausnahme zu vermeiden. Schätzen Sie jede Hilfe.
4 Antworten
Ihre Liste wird nicht leer sein, sondern eine Liste mit leeren Listen. Sie können die folgenden Schritte ausführen, um die Musterübereinstimmung basierend auf der ersten Unterliste durchzuführen (vorausgesetzt, Mat stellt die Konsistenz der Datenstruktur sicher).
rl [] = []
rl ([]:_) = []
rl m = map last m : (rl (map init m))
rl mat
[[3,5,6],[2,4,0],[1,0,0]]
Sie vermissen den zweiten Fall.
Ich bin ein alter Mann in Eile. Ich würde es so machen (Data.List
importieren)
rotl :: [[x]] -> [[x]]
rotl = transpose . map reverse
rotateLeft [] = []
rotateLeft ([]:_) = []
rotateLeft (h:t) = (map last (h:t)):(rotateLeft (map init (h:t)))
Das erste Muster gilt für den Fall, dass der Kopf der Listenliste länger als andere Elemente ist.
Sie haben das zweite Muster falsch verstanden: Wenn wir eine richtige Matrix haben (dh Elemente sind gleich lang), ist der Basisfall eine Liste leerer Listen. Sie haben jedoch [[]] geschrieben, was nur dann zutrifft, wenn die ursprüngliche Liste aus einer einzelnen Liste besteht.
Das Problem ist, dass Ihr Muster nicht übereinstimmt. Wir gehen durch die Funktionen Ihres Codes und beginnen mit:
Prelude> let x = [[1,2,3],[0,4,5],[0,0,6]]
Prelude> :m +Data.List
Prelude Data.List> map last x
[3,5,6]
Prelude Data.List> let y = map init x
Prelude Data.List> y
[[1,2],[0,4],[0,0]]
Prelude Data.List> map last y
[2,4,0]
Prelude Data.List> let z = map init y
Prelude Data.List> z
[[1],[0],[0]]
Prelude Data.List> map last z
[1,0,0]
Prelude Data.List> map init z
[[],[],[]]
Das Grundproblem besteht also darin, dass Ihr Basisfall, mit dem Sie übereinstimmen, nicht [[],[],[]]
ist, sondern [[]]
, sodass das Muster nicht übereinstimmt.
Sie haben jetzt mehr oder weniger drei Möglichkeiten: Sie können (a) versuchen zu beenden, wenn die erste leere Liste angezeigt wird; Dies wird in Haskell als any null
geschrieben, wobei die Funktion any
und die Funktion null
verwendet werden, die beide im Präludium definiert sind. oder (b) Sie können fest codieren, dass dies nur für 3x3-Matrizen funktioniert, und nur mit [[],[],[]]
übereinstimmen, oder (c) Sie können versuchen, zu beenden, wenn alle Listen leer sind (all null
). In diesem Fall Sie können entweder nicht vorhandene Elemente überspringen oder alles in den Datentyp Maybe x
einschließen, sodass fehlende Elemente durch Nothing
dargestellt werden, während vorhandene Elemente durch Just x
dargestellt werden.
Verwandte Fragen
Neue Fragen
haskell
Haskell ist eine funktionale Programmiersprache mit starker statischer Typisierung, verzögerter Auswertung, umfassender Unterstützung für Parallelität und Parallelität sowie einzigartigen Abstraktionsfunktionen.