2016-07-12 18 views
-1

Ich habe gelesen The Art of Computer Programming, und obwohl es seine Momente der höheren Mathematik hat, die ich einfach nicht bekommen kann, haben einige Übungen Spaß gemacht zu tun.Wie extrahiere ich einen Algorithmus aus diesen Anweisungen?

Nachdem ich einen von ihnen getan habe, gehe ich zu der Antwort über, ob ich besser oder schlechter als das tat, was das Buch vorschlägt (normalerweise schlechter), aber ich bekomme nicht, was die Antwort für das gegenwärtige I Ich versuche überhaupt zu vermitteln.

Das Buch Frage und vorgeschlagene Lösung kann here

ich verstanden, was zu finden, ist, dass t die Anzahl der sein kann ‚fehlenden‘ Elemente oder eine allgemeine konstant sein, aber was wirklich verstehe ich nicht ist die scheinbar willkürliche Anweisung, sie basierend auf ihren Komponenten zu sortieren, was für mich so aussieht, als würden Sie Ihre Räder drehen, denn auf den ersten Blick bringt es Sie nicht näher an die ursprüngliche Reihenfolge heran. Und die Entscheidung (unter anderem), einen Teil der gepaarten Namen durch eine Zahl zu ersetzen (Datei G enthält alle Paare (i, xi) für n-t < i ≤ n).

Also meine Frage ist, einfach, Wie extrahiere ich einen Algorithmus aus dieser Antwort?

Bit einer Klarstellung:

Ich verstehe, was es tun soll, und wie würde ich mich in sie in C++ übersetzen. Was ich nicht verstehe, ist, warum ich die Kopien der Eingabedatei sortieren soll, und wenn ja, nach welchen Kriterien sortiere ich, sowie nach den Gründen, um eine Seite der Paare zu einer Zahl zu ändern.

+1

Die einzige Antwort, die ich mir vorstellen kann, ist "Diese Antwort _ist_ der Algorithmus. Es gibt nichts zu extrahieren.". Aber da Sie es als C++ markiert haben, wollte ich vermutlich wissen, wie Sie einen Algorithmus in C++ konvertieren. Und das ist meistens eine Frage des sorgfältigen Lesens. – MSalters

+0

Die Daten repräsentieren eine verkettete Liste. Jeder bestimmte Datenwert wird zweimal vorkommen, mit Ausnahme des ersten und des letzten Elements. Verknüpfen Sie es in der richtigen Reihenfolge. – Logicrat

+1

Mit der Bearbeitung vermute ich, dass Sie den Punkt von TAOCP vermissen. Es ist einer der schwierigsten Texte, also erwarte nicht, es auf einen Blick zu verstehen. Lesen. Jeden. Wort. In diesem Fall scheinen Sie den Hintergrund zu vermissen. _Wenn Sie unter den gegebenen Einschränkungen arbeiten (kein wahlfreier Zugriff), welche alternative Lösung benötigen Sie? Weil es ohne diese Einschränkungen ein Anfängerbeispiel wäre. TAOCP ist das kanonische Comp.Sci-Lehrbuch, das Ihnen beibringt, wie Sie Probleme angehen, die keine offensichtliche Lösung bieten. – MSalters

Antwort

0

Es wird angenommen, dass die Namen sortierbar sind und dass eine ausreichende Anzahl von Bandlaufwerken vorhanden ist, um das Problem zu lösen. Definieren Sie ein Paar als (name, nächster_name), wobei nächster_name der Name der Person im Westen ist. Eine Kopie der Dateipaare wird auf ein anderes Band kopiert. Die erste Datei ist nach ihrem Namen sortiert, die zweite Datei ist nach next_name sortiert. Tape-Sortierungen sind Bottom-Up-Merge-Sort oder eine komplexere Variante namens Polyphase Merge Sort, aber für dieses Problem ist Standard-Bottom-Up-Merge-Sortierung gut genug. Für C++ könnten Sie std :: stable_sort() verwenden, um eine Bandsortierung zu emulieren, eine Lambda-Funktion für den Vergleich zu verwenden, nach der ersten Datei nach Namen zu sortieren und nach der zweiten Datei nach next_name zu sortieren.

Die Terminologie für die Indexierung verwendet den Namen [1], um den östlichsten Namen zu repräsentieren, und den Namen [n], um den westlichsten Namen zu repräsentieren.

Nach der anfänglichen Sortierung der zwei Dateien von Paaren, die Lösung besagt, dass "Übergabe über die Dateien" getan wird, um den vorletzten Namen, Name [n-1] zu identifizieren, aber nicht angeben, wie. Dabei nehme ich an, dass auch name [n] identifiziert wird. Die Dateien werden nacheinander verglichen, wobei der Name der ersten Datei mit dem Namen next_name der zweiten Datei verglichen wird. Eine Nichtübereinstimmung gibt entweder den ersten Namen, den Namen [1] oder den Nachnamen, den Namen [n] oder in einem sehr seltenen Fall an, und die nächsten Paare aus jeder Datei müssen überprüft werden, um festzustellen, was die fehlende Übereinstimmung anzeigt. Zu dem Zeitpunkt, zu dem der letzte Name, Name [n] identifiziert wird, wird der Name aus dem zweiten Dateipaar der vorletzte Name sein, Name [n-1].

Sobald der Name [n-1] und der Name [n] bekannt sind, wird eine merge-ähnliche Operation unter Verwendung beider Dateien ausgeführt. Name [n-1] und name [n] werden mit Paaren (name [i ], name [i + 2]) für i = 1 bis n-2 (in der Reihenfolge der Namen) und G mit zwei Paaren (n-1, x [n-1]) und (n, x [n]) , auch in der Namensreihenfolge (G und G 'sind in der Namensreihenfolge bis zum letzten Schritt).

F wird nach H kopiert, und ein iterativer Prozess wird wie im Algorithmus beschrieben durchgeführt, wobei t jedes Mal verdoppelt wird, 2, 4, 8, ....Nach jedem Durchlauf enthält F 'Paare (x [i], x [i + t]) für i = 1 bis nt, dann wird G' sortiert und mit G wieder in G 'verschmolzen, was zu einem G' führt, das das enthält Paare (i, x [i]) für i = nt bis n, in der Reihenfolge der Namen. Schließlich enden alle Paare in G (i, x [i]) für i = 1 bis n, in der Reihenfolge ihrer Namen, und dann wird G nach dem Index (linker Teil des Paares) sortiert, was zu den Namen in sortierter Reihenfolge führt.

+0

Vielen Dank. – RiggedDeath

+0

@RiggedDeath - Ich habe die Antwort aktualisiert, um zu erklären, wie der anfängliche Nachname und der Nachname behandelt werden. Die Algorithmusbeschreibung erläutert, wie fortgefahren wird, sobald die anfänglichen F- und G-Dateien erstellt wurden. – rcgldr