Permutation Algorithm in Haskell

user2573189

I read this permutation function example in a Haskell textbook and I was wondering if someone could help me understand what is happening. Also, assume that the function delete simply deletes the first occurrence of a value from a list and returns the list

perms [] = [[]]
perms p = [x:xs | x <-p, xs <- perms (delete x p)]

I understand that an empty list equals a list with an empty list. For all other cases the head of the list is prepended to x and the numbers except the head recurses through the algorithm.

My question is how does this work, for example, my pseudocode understanding is

perms[1,2,3]
x <- 1
xs <- [2,3]
perms [2,3]
x <- 2
xs <- 3
perms [3]
x <- 3
xs <- []

this would produce the list [1,2,3] how does the algorithm produce the other list results.

An output of this code working is as follows:

>perms [1,2,3]
[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 
K. A. Buhr

The expression:

[x:xs | x <- p, xs <- perms (delete x p)]

is a list comprehension, which means that each of the a <- b expressions on the right hand side form a sort of implicit loop that your pseudocode doesn't account for.

Written in pseudocode with explicit loops, it's equivalent to:

for each x in p:
  for each xs in perms (delete x p):
    yield (x:xs)
-- and return the list of all results yielded

It can then be helpful to think through the definition recursively from the bottom up. If you run perm [n] for any n, then the outer loop is only evaluated for x = n, and since:

perms (delete n [n]) = perms [] = [[]]

the inner loop is equivalent to:

for each xs in [[]]
  ...

and is only evaluated for xs = []. Therefore, only one value is yielded:

x:xs = n:[] = [n]

So, perm [n] gives a list of the single element [n], in other words [[n]].

If you move on to perm [1,2] and imagine unfolding the loops:

-- for each x in [1,2]
first, for x = 1
  -- for each xs in perms (delete 1 [1,2]) = perms [2] = [[2]]
  so only for xs = [2]
    yield (x:xs) = yield (1:[2]) = yield [1,2]
second, for x = 2
  -- for each xs in perms (delete 2 [1,2]) = perms [1] = [[1]]
  so only for xs = [1]
    yield (x:xs) = yield (2:[1]) = yield [2,1]

so two values are yielded, namely [1,2] and [2,1], giving:

perm [1,2] = [[1,2],[2,1]]

This obviously generalizes to any perm [a,b] = [[a,b],[b,a]], so we can finally calculate perm [1,2,3]:

-- for each x in [1,2,3]
first, for x = 1
  -- for each xs in perms (delete 1 [1,2,3]) = perms [2,3] = [[2,3],[3,2]]
  first for xs = [2,3]
    yield (x:xs) = yield (1:[2,3]) = yield [1,2,3]
  second for xs = [3,2]
    yield (x:xs) = yield [1,3,2]
second, for x = 2
  -- for each xs in perms (delete 2 [1,2,3]) = [[1,3],[3,1]]
  first for xs = [1,3]
    yield (x:xs) = yield [2,1,3]
  second for xs = [3,1]
    yield (x:xs) = yield [2,3,1]
third, for x = 3
  first for xs = [1,2]
    yield [3,1,2]
  second for xs = [2,1]
    yield [3,2,1]

In all, six values are yielded, giving the list:

perms [1,2,3] = [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.

Bei Verstößen wenden Sie sich bitte [email protected] Löschen.

bearbeiten am
0

Lass mich ein paar Worte sagen

0Kommentare
LoginNach der Teilnahme an der Überprüfung

Verwandte Artikel

TOP Liste

  1. 1

    So legen Sie mit dem Interface Builder unterschiedliche führende Speicherplätze für unterschiedliche Geräte fest

  2. 2

    Wie konvertiere ich einen Vektor von Bytes (u8) in eine Zeichenfolge?

  3. 3

    Wie kann ich in SCSS mehrere Klassen zu einer einzigen kombinieren?

  4. 4

    Eclipse Oxygen - Projekte verschwinden

  5. 5

    Wie konvertiert man einen Datenrahmen im langen Format in eine Liste mit einem geeigneten Format?

  6. 6

    Wie kann ich den Kaskadenmodus global einstellen?

  7. 7

    Wie erstelle ich einen neuen übergeordneten Knoten außerhalb der .ref (/ path) in der Firebase-Echtzeitdatenbank mithilfe von Cloud-Funktionen (Typescript)?

  8. 8

    So erhalten Sie eine gleichmäßige Höhe für alle Eingabefelder

  9. 9

    Python: Spalten mit demselben Namen zusammenführen, wobei der Mindestwert beibehalten wird

  10. 10

    Speichern Sie ein MPAndroidChart-Diagramm in einem Bild, ohne es in einer Aktivität anzuzeigen

  11. 11

    Gruppieren Sie Datenrahmenspalten nach ihrem Datum (die Spaltentitel enthalten) und fassen Sie die Instanzen von Einsen und Nullen in R . zusammen

  12. 12

    ElasticSearch BulkShardRequest ist aufgrund von org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor fehlgeschlagen

  13. 13

    Tic Tac Toe-Spiel im React-Reset-Button funktioniert nicht

  14. 14

    Tomcat - Leiten Sie den alten Kontextstamm zum neuen Kontextstamm um

  15. 15

    Wie wählt man Unterschiede mit drei Tabellen aus?

  16. 16

    Ärgerliches Problem mit yaml, das ich nicht lösen kann

  17. 17

    Wie kann ich meine Tabelle abfragen, um sie in mySQL nach 2 Feldern zu gruppieren?

  18. 18

    So berechnen Sie die Verfügbarkeit von Anwendungen (SLA)

  19. 19

    Fügen Sie eine weitere Schaltfläche zu gwt Suggest Box hinzu

  20. 20

    Modbus Python Schneider PM5300

  21. 21

    Wie kann eine gleichmäßige Lastverteilung in ElasticSearch mit Indizes mit unterschiedlicher Anzahl von Shards erreicht werden?

heißlabel

Archiv