Saturday 14 October 2017

Moving Average Array Java


2.4 Prioritäts-Warteschlangen Viele Anwendungen erfordern, dass wir Elemente mit Schlüssel in Reihenfolge, aber nicht unbedingt in voller Reihenfolge sortiert und nicht unbedingt alle auf einmal. Oft sammeln wir einen Satz von Elementen, dann verarbeiten die mit dem größten Schlüssel, dann vielleicht sammeln mehr Elemente, dann verarbeiten die mit dem aktuellen größten Schlüssel, und so weiter. Ein geeigneter Datentyp in einer solchen Umgebung unterstützt zwei Vorgänge: das Maximum entfernen und einfügen. Ein solcher Datentyp wird als Prioritätswarteschlange bezeichnet. Prioritätswarteschlangen sind durch das Entfernen der Maximal - und Einfügeoperationen gekennzeichnet. Durch die Konvention werden wir die Schlüssel nur mit einer less () Methode vergleichen, wie wir es für die Sortierung getan haben. Wenn also Datensätze doppelte Schlüssel haben können, bedeutet maximum einen Datensatz mit dem größten Schlüsselwert. Um die API zu vervollständigen, müssen wir auch Konstruktoren und einen Test hinzufügen, wenn leere Operation. Für die Flexibilität verwenden wir eine generische Implementierung mit einem generischen Typ Key, der Comparable implementiert. Programm TopM. java ist ein Prioritätswarteschlangen-Client, der ein Befehlszeilenargument M aufnimmt. Liest Transaktionen von der Standard-Eingabe und druckt die M größten Transaktionen aus. Elementare Implementierungen. Die grundlegenden Datenstrukturen, die wir in Abschnitt 1.3 besprochen haben, bieten uns vier unmittelbare Ausgangspunkte für die Implementierung von Prioritätsschlangen. Array-Darstellung (ungeordnet). Vielleicht basiert die einfachste Prioritätswarteschlangenimplementierung auf unserem Code für Pushdown-Stacks. Der Code für das Einfügen in die Prioritätswarteschlange ist derselbe wie für den Push im Stack. Um zu implementieren, entfernen Sie die maximale. Können wir Code wie die innere Schleife der Auswahlart hinzufügen, um das maximale Element mit dem Element am Ende auszutauschen und dann zu löschen, wie wir es mit pop () für Stacks getan haben. Programm UnorderedArrayMaxPQ. java implementiert eine Prioritätswarteschlange mit diesem Ansatz. Array-Darstellung (geordnet). Ein anderer Ansatz besteht darin, Code für insert hinzuzufügen, um größere Einträge um eine Position nach rechts zu verschieben, wodurch die Einträge im Array in der Reihenfolge (wie beim Einfügen von Sortierungen) beibehalten werden. Somit ist das größte Element immer am Ende, und der Code zum Entfernen des Maximums in der Prioritätswarteschlange ist das gleiche wie für den Pop in dem Stapel. Das Programm OrderedArrayMaxPQ. java implementiert mit diesem Ansatz eine Prioritätswarteschlange. Verknüpfte Darstellungen (ungeordnete und umgekehrte Reihenfolge). Ähnlich können wir mit dem Linklistencode für Pushdown-Stacks beginnen, indem wir entweder den Code für pop () ändern, um das Maximum oder den Code für push () zu finden und zurückzusetzen, um Gegenstände in umgekehrter Reihenfolge und den Code für pop () zu halten Unlink und geben Sie das erste (maximale) Element in der Liste zurück. Alle gerade diskutierten elementaren Implementierungen haben die Eigenschaft, daß entweder die Einfügung oder die Entfernen der maximalen Operation im schlimmsten Fall eine lineare Zeitdauer annimmt. Die Suche nach einer Implementierung, bei der beide Operationen garantiert schnell sind, ist eine interessantere Aufgabe, und sie ist das Hauptthema dieses Abschnitts. Heap-Definitionen. Der binäre Heap ist eine Datenstruktur, die die grundlegenden Prioritäts-Warteschlangenoperationen effizient unterstützen kann. In einem binären Heap werden die Elemente in einem Array gespeichert, so dass sichergestellt ist, dass jede Taste größer als (oder gleich) der Tasten an zwei anderen spezifischen Positionen ist. Im Gegenzug muss jeder dieser Schlüssel größer sein als zwei weitere Tasten und so weiter. Diese Reihenfolge ist leicht zu sehen, wenn wir die Schlüssel als in einer binären Baumstruktur mit Kanten von jeder Taste zu den beiden Schlüsseln, die bekannter kleiner zu sein. Definition. Ein binärer Baum ist heap-ordered, wenn der Schlüssel in jedem Knoten größer als (oder gleich) ist die Schlüssel in diesem Knoten zwei Kinder (falls vorhanden). Aussage. Der größte Schlüssel eines heapgeordneten Binärbaums befindet sich im Stammverzeichnis. Wir können die heap-ordering Einschränkung für jeden binären Baum. Es ist jedoch besonders bequem, einen vollständigen Binärbaum zu verwenden, wie der untenstehende. Wir stellen vollständige Binärbäume sequentiell innerhalb eines Arrays dar, indem wir die Knoten mit der ebenen Ordnung setzen. Mit der Wurzel an Position 1, ihre Kinder an den Positionen 2 und 3, ihre Kinder in den Positionen 4, 5, 6 und 7, und so weiter. Definition. Ein binärer Heap ist ein Satz von Knoten mit Schlüsseln, die in einem vollständigen Heap-geordneten Binärbaum angeordnet sind und in einer Reihenfolge in einem Array (nicht unter Verwendung des ersten Eintrags) dargestellt sind. In einem Haufen befindet sich das Elternteil des Knotens in der Position k in der Position k2, und umgekehrt befinden sich die beiden Kinder des Knotens in der Position k in den Positionen 2k und 2k1. Wir können auf und ab reisen, indem wir einfache Arithmetik auf Array-Indizes durchführen : Um den Baum von ak zu bewegen, setzen wir k auf k2, um den Baum zu senken, den wir k auf 2k oder 2k1 setzen. Algorithmen auf Haufen. Wir stellen einen Haufen der Größe N im privaten Array pq der Länge N1 dar, wobei pq0 unbenutzt ist und der Haufen in pq1 bis pqN. Wir greifen auf Schlüssel nur über private Helferfunktionen less () und exch () zu. Die Heap-Operationen, die wir betrachten, indem wir zuerst eine einfache Modifikation durchführen, die die Heap-Bedingung verletzen könnte, und dann durch den Heap reisen, wobei der Heap modifiziert wird, um sicherzustellen, daß die Heap-Bedingung überall erfüllt ist. Wir bezeichnen diesen Prozess als Wiedererwärmung. Oder Wiederherstellen der Heap-Reihenfolge. Bottom-up reheapify (schwimmen). Wenn der Heap-Befehl verletzt wird, weil ein Knoten-Schlüssel größer als der Knoten-Schlüssel ist, dann können wir Fortschritte in Richtung Festlegung der Verletzung durch den Austausch des Knotens mit seinem Elternteil machen. Nach dem Austausch ist der Knoten größer als seine beiden Kinder (einer ist der alte Elternteil und der andere ist kleiner als der alte Elternteil, weil er ein Kind dieses Knotens war), aber der Knoten kann immer noch größer als sein Elternteil sein. Wir können diese Verletzung in der gleichen Weise beheben, und so weiter, bewegen Sie den Haufen, bis wir einen Knoten mit einem größeren Schlüssel oder der Wurzel erreichen. Top-down heapify (Waschbecken). Wenn der Heap-Befehl verletzt wird, weil eine Knotetaste kleiner als eine oder beide Knöpfe der Knotenskinder wird, können wir Fortschritte in Richtung der Festsetzung des Verstoßes durch Austauschen des Knotens mit dem größeren seiner beiden Kinder machen. Dieser Schalter kann zu einer Verletzung des Kindes führen wir diesen Verstoß auf die gleiche Weise und so weiter, bewegen sich den Haufen, bis wir einen Knoten mit beiden Kindern kleiner oder der Unterseite erreichen. Heap-basierte Prioritätswarteschlange. Diese sink () - und swim () - Operationen bilden die Grundlage für die effiziente Implementierung der API für die Prioritätswarteschlange, wie unten dargestellt und in MaxPQ. java und MinPQ. java implementiert. Einfügen. Wir addieren das neue Element am Ende des Arrays, erhöhen die Größe des Heaps und schwimmen dann durch den Heap mit diesem Item, um die Heap-Bedingung wiederherzustellen. Entfernen Sie das Maximum. Wir nehmen das größte Element von der Spitze, legen Sie das Element vom Ende des Haufens an der Spitze, dekrementieren die Größe des Haufens, und dann sinken Sie durch den Haufen mit diesem Element, um die Heap-Zustand wiederherzustellen. Aussage. In einer N-Item-Prioritätswarteschlange benötigen die Heap-Algorithmen nicht mehr als 1 lg N für einen Vergleich und nicht mehr als 2 lg N zum Vergleichen des Maximums. Praktische Überlegungen. Wir schließen unsere Studie der Heap-Priorität Warteschlange API mit ein paar praktische Überlegungen. Mehrfachhaufen. Es ist nicht schwierig, unseren Code zu modifizieren, um Haufen zu erstellen, basierend auf einer Array-Repräsentation von kompletten, heapgeordneten ternären oder d-armen Bäumen. Es gibt einen Kompromiß zwischen den niedrigeren Kosten von der reduzierten Baumhöhe und den höheren Kosten für das Finden der größten der drei oder d Kinder an jedem Knoten. Größenänderung des Arrays. Wir können einen no-Argument-Konstruktor, Code für die Arrayverdopplung in insert () hinzufügen. Und Code für die Array-Halbierung in delMax (). Genauso wie bei den Stapeln in Abschnitt 1.3. Die logarithmischen Zeitgrenzen werden amortisiert, wenn die Größe der Prioritätswarteschlange beliebig ist und die Arrays die Größe ändern. Unveränderlichkeit der Tasten. Die Prioritätswarteschlange enthält Objekte, die von Clients erstellt werden, setzt aber voraus, dass der Clientcode die Schlüssel nicht ändert (was die Heap-Invarianten ungültig machen könnte). Index-Prioritätswarteschlange. In vielen Anwendungen ist es sinnvoll, Clients auf Elemente zu verweisen, die sich bereits auf der Prioritätswarteschlange befinden. Eine einfache Möglichkeit, dies zu tun, ist die Zuordnung eines eindeutigen Integer-Index mit jedem Element. IndexMinPQ. java ist eine Heap-basierte Implementierung dieser API IndexMaxPQ. java ist ähnlich, aber für maximal orientierte Priorität Warteschlangen. Multiway. java ist ein Client, der mehrere sortierte Eingangsströme in einen sortierten Ausgangsstrom zusammenführt. Wir können jede Prioritätswarteschlange verwenden, um eine Sortiermethode zu entwickeln. Wir setzen alle Schlüssel ein, die in eine minimal orientierte Prioritätswarteschlange zu sortieren sind, und dann wiederholt das Minimum entfernen, um sie alle in der Reihenfolge zu entfernen. Wenn Sie einen Heap für die Prioritätswarteschlange verwenden, erhalten wir heapsort. Wenn wir uns auf die Aufgabe der Sortierung konzentrieren, verlassen wir die Vorstellung, die Heap-Darstellung der Prioritätswarteschlange zu verstecken und benutzen Sie swim () und sink () direkt. Auf diese Weise können wir ein Array sortieren, ohne dass zusätzlicher Speicherplatz benötigt wird, indem der Heap innerhalb des zu sortierenden Arrays beibehalten wird. Heapsort bricht in zwei Phasen ein: Haufenbau. Wo wir das ursprüngliche Array zu einem Heap reorganisieren und die Sortierung. Wo wir die Elemente aus dem Haufen in absteigender Reihenfolge ziehen, um das sortierte Ergebnis zu erstellen. Haufenbau. Wir können diese Aufgabe in Zeit proportional zu N lg N, indem wir von links nach rechts durch das Array, mit swim (), um sicherzustellen, dass die Einträge auf der linken Seite des Scan-Zeiger einen heap-geordneten kompletten Baum, wie sukzessive Prioritätswarteschlangeneinfügungen. Eine clevere Methode, die viel effizienter ist, von rechts nach links, mit sink (), um Unterhaufen zu machen, wie wir gehen. Jede Position im Array ist die Wurzel eines kleinen Subheap-Sink () funktioniert oder solche Subheaps, wie gut. Wenn die beiden Kinder eines Knotens Haufen sind, macht das Aufrufen von sink () auf diesem Knoten den Teilbaum, der dort einen Haufen verwurzelt hat. Sortierung. Der Großteil der Arbeit während der Heapsort wird während der zweiten Phase durchgeführt, wo wir die größten verbleibenden Elemente aus dem Haufen entfernen und sie in die Array-Position leeren, wenn der Haufen schrumpft. Heap. java ist eine vollständige Implementierung von heapsort. Unten ist eine Spur des Inhalts des Arrays nach jeder Senke. Aussage. Senken-basierte Heap-Konstruktion ist lineare Zeit. Aussage. Heapsort-Benutzer weniger als 2n lg n vergleichen und tauschen zu sort n Elemente. Die meisten Gegenstände reinsert in den Heap während der Sortierung gehen den ganzen Weg nach unten. Wir können dadurch Zeit sparen, indem wir die Überprüfung vermeiden, ob das Element seine Position erreicht hat, indem wir einfach das größere der beiden Kinder fördern, bis der Boden erreicht ist, und dann den Haufen wieder in die richtige Position bringen. Diese Idee schneidet die Zahl der Vergleiche um den Faktor 2 zu Lasten der zusätzlichen Buchhaltung. Angenommen, die Sequenz (wobei ein Buchstabe bedeutet einfügen und ein Sternchen das Maximum entfernen) wird auf eine anfänglich leere Prioritätswarteschlange angewendet. Geben Sie die Sequenz der zurückgegebenen Werte an, indem Sie die maximalen Operationen entfernen. Lösung. R............................................................. Lösung. Muss den maximalen Wert von scratch nach einem Remove-the-Maximum-Vorgang aktualisieren. Bereitstellen von Prioritätswarteschlangenimplementierungen, die das Einfügen unterstützen und das Maximum entfernen. Eine für jede der folgenden zugrunde liegenden Datenstrukturen: ungeordnetes Array, geordnetes Array, ungeordnete verkettete Liste und geordnete verkettete Liste. Geben Sie für jede der vier Implementierungen aus der vorherigen Übung eine Tabelle der Worst-Case-Schranken für jede Operation an. Teilweise Lösung. OrderedArrayMaxPQ. java und UnorderedArrayMaxPQ. java Ist ein Array, das in absteigender Reihenfolge ein max-orientiertes Heap sortiert wird. Antworten. Ja. Angenommen, Ihre Anwendung wird eine große Anzahl von Insert-Operationen haben, aber nur wenige entfernen Sie die maximale Operationen. Welche Prioritäts-Warteschlangen-Implementierung meinst du, wäre am effektivsten: heap, ungeordnetes Array, geordnetes Array Antwort. Ungeordnetes Array. Insert ist konstante Zeit. Angenommen, Ihre Anwendung wird eine große Anzahl von finden die maximale Operationen haben, aber eine relativ kleine Anzahl von Insert und entfernen Sie die maximale Operationen. Welche Prioritätswarteschlangen-Implementierung meinst du, wäre am effektivsten: heap, ungeordnetes Array, geordnetes Array Antwort. Sortiertes Array. Das Maximum ist die konstante Zeit. Was ist die minimale Anzahl von Elementen, die ausgetauscht werden müssen während eines Entfernens die maximale Operation in einem Haufen der Größe N ohne doppelte Schlüssel Geben Sie einen Haufen der Größe 15, für die das Minimum erreicht wird. Beantworten Sie die gleiche Frage für zwei und drei sukzessive entfernen Sie die maximale Operationen. Teilweise Antwort. (A) 2. Entwerfen Sie einen Linearzeit-Zertifizierungsalgorithmus, um zu überprüfen, ob ein Array pq ein min-orientierter Heap ist. Lösung. Siehe die Methode isMinHeap () in MinPQ. java. Beweisen, dass Senken-basierte Heap-Konstruktion verwendet höchstens 2 n vergleicht und am meisten n Austäusche. Lösung. Es genügt, zu beweisen, dass Senken-basierte Heap-Konstruktion weniger als n Austäusche verwendet, da die Anzahl der Vergleiche höchstens das Zweifache der Anzahl von Austäuschen beträgt. Der Einfachheit halber sei angenommen, daß der binäre Haufen vollkommen ist (d. h. ein binärer Baum, in dem jede Ebene abgeschlossen ist) und die Höhe h hat. Wir definieren die Höhe eines Knotens in einem Baum als Höhe des Teilbaums, der an diesem Knoten verwurzelt ist. Ein Schlüssel in der Höhe k kann mit höchstens k Schlüsseln unter ihm ausgetauscht werden, wenn er versenkt wird. Da es 2 h minus k Knoten in der Höhe k gibt. Die Gesamtzahl der Austausche ist höchstens: Die erste Gleichheit ist für eine nichtstandardisierte Summe, aber es ist einfach zu überprüfen, ob die Formel über die mathematische Induktion gilt. Die zweite Gleichheit gilt, weil ein perfekter binärer Baum der Höhe h 2 h 1 minus 1 Knoten hat. Der Nachweis, dass das Ergebnis gilt, wenn der binäre Baum nicht perfekt ist erfordert ein bisschen mehr Pflege. Sie können dies mit der Tatsache, dass die Anzahl der Knoten in der Höhe k in einem binären Heap auf n Knoten ist höchstens ceil (n 2 k 1). Alternative Lösung. Wiederum der Einfachheit halber sei angenommen, daß der binäre Haufen perfekt ist (d. h. ein binärer Baum, in dem jede Ebene abgeschlossen ist). Wir definieren die Höhe eines Knotens in einem Baum als Höhe des Teilbaums, der an diesem Knoten verwurzelt ist. Zuerst beobachte, dass ein binärer Heap auf n Knoten n minus 1 Links hat (weil jede Verknüpfung das übergeordnete Element eines Knotens ist und jeder Knoten eine übergeordnete Verknüpfung außer dem Stammverzeichnis hat). Sinking einen Knoten der Höhe k erfordert höchstens k Austäusche. Wir werden k Verbindungen zu jedem Knoten in der Höhe k aufladen. Aber nicht notwendigerweise die Verbindungen auf dem Weg, der genommen wird, wenn der Knoten versenkt wird. Stattdessen laden wir den Knoten auf, der die k-Verknüpfungen entlang des Pfads von dem Knoten, der links-rechts-rechts-rechts-verläuft, verknüpfen. Zum Beispiel, in dem Diagramm unten, wird der Wurzelknoten die vier roten Verbindungen aufgeladen, wobei der blaue Knoten die 3 blauen Verbindungen und so weiter aufgeladen wird. Beachten Sie, dass keine Verbindung zu mehr als einem Knoten geladen wird. (In der Tat gibt es zwei Links, die nicht zu einem Knoten geladen werden: die rechte Verbindung von der Wurzel und der übergeordneten Verknüpfung von dem unteren rechten Knoten.) Somit ist die Gesamtzahl der Vermittlungen höchstens n. Da es höchstens 2 Vergleiche pro Austausch gibt, beträgt die Anzahl der Vergleiche höchstens 2 n. Kreative Probleme Rechnerische Zahlentheorie. Schreiben Sie ein Programm CubeSum. java, das alle ganzen Zahlen des Formulars a 3 b 3 ausgibt, wobei a und b ganze Zahlen zwischen 0 und N in sortierter Reihenfolge sind, ohne übermäßigen Speicherplatz zu verwenden. Das heißt, anstatt ein Array der N 2 Summen zu berechnen und zu sortieren, baut man eine minimal orientierte Prioritätswarteschlange, die anfänglich (0 3 0, 0), (1 3 1, 0), (2 3 2 , 0). (N & sub3; N, 0). Wenn die Prioritätswarteschlange nicht leer ist, entfernen Sie das kleinste Element (i 3 j 3 i, j), drucken Sie es aus, und dann, wenn j 3 (j1) 3. i, j1). Verwenden Sie dieses Programm, um alle verschiedenen ganzen Zahlen a, b, c und d zwischen 0 und 106 zu finden, so dass ein 3 b 3 c 3 d 3 z. 1729 93 103 13 123. Finden Sie das Minimum. Fügen Sie eine min () - Methode zu MaxPQ. java hinzu. Ihre Umsetzung sollte mit konstanter Zeit und konstanten zusätzlichen Platz. Lösung. Fügen Sie eine zusätzliche Instanzvariable hinzu, die auf die minimale Position verweist. Aktualisieren Sie es nach jedem Aufruf von insert (). Setzen Sie es auf Null zurück, wenn die Prioritätswarteschlange leer wird. Dynamisch-medianer Befund. Entwerfen Sie einen Datentyp, der das Einfügen in logarithmischer Zeit unterstützt, den Median in konstanter Zeit finden und den Median in logarithmischer Zeit entfernen. Lösung. Halten Sie den Medianschlüssel in v einen max-orientierten Heap für Schlüssel kleiner als der Schlüssel von v verwenden ein min-orientierte Heap für Schlüssel größer als der Schlüssel von v. Um einzufügen, fügen Sie den neuen Schlüssel in den entsprechenden Heap, ersetzen v mit Wobei der Schlüssel aus diesem Haufen extrahiert wird. Untergrenze. Beweisen, dass es unmöglich ist, eine Implementierung der MinPQ-API zu entwickeln, so dass beide einfügen und löschen die Mindestgarantie für die Verwendung von N log log N vergleicht. Lösung. Dies würde zu einem N log log N Vergleichsbasierten Sortieralgorithmus führen (die N Elemente einfügen, dann das Minimum wiederholt entfernen), wodurch der Satz von Abschnitt 2.3 verletzt wird. Index-Prioritäts-Warteschlangen-Implementierung. Implementieren Sie IndexMaxPQ. java durch Ändern von MaxPQ. java wie folgt: Ändern Sie pq, um Indizes zu halten, fügen Sie eine Array-Schlüssel, um die Schlüsselwerte zu halten, und fügen Sie ein Array qp, das die Umkehrung von pq mdash qpi gibt die Position von i in pq (die So daß pqj i ist). Ändern Sie dann den Code, um diese Datenstrukturen zu pflegen. Verwenden Sie die Konvention, dass qpi -1 ist, wenn i nicht in der Warteschlange ist, und enthalten eine Methode contains (), die diese Bedingung testet. Sie müssen die Hilfsmethoden exch () und less (), aber nicht sink () oder swim () ändern. Web-Übungen Beste, durchschnittliche und schlimmsten Fall von heapsort. Was ist der beste Fall, der durchschnittliche Fall und der ungünstigste Fall der Anzahl der Vergleiche für heapsorting ein Array der Länge N Lösung. Wenn wir Duplikate zulassen, ist der beste Fall lineare Zeit (N gleiche Schlüssel), wenn wir Duplikate nicht zulassen, der beste Fall ist N lg N vergleicht (aber die beste Eingabe ist nicht trivial). Die durchschnittliche und schlechteste Fallzahl von Vergleichen ist 2 N lg N verglichen. Details finden Sie unter Die Analyse von Heapsort. Beste und schlechteste Fall von heapify. Was ist die geringste und die meisten Zahl der Vergleichsexchanges, die benötigt werden, um ein Array von N Elementen zu heapisieren. Das Heapen eines Arrays von N Elementen in absteigender Reihenfolge erfordert 0 Austäusche und N - 1 vergleicht. Heaping ein Array von N Elemente in aufsteigender Reihenfolge erfordert N Börsen und 2N vergleicht. Steuernummern. Finden Sie die kleinsten ganzen Zahlen, die als Summe von Cubes von Ganzzahlen auf zwei verschiedene Arten ausgedrückt werden können (1.729), drei verschiedene Arten (87.539.319), vier verschiedene Wege (6.963.472, 309.248), fünf verschiedene Wege (48.988.659.276.962.496) und sechs verschiedene Wege (24.153.319.581.254.312.065.344 ). Solche Ganzzahlen werden nach der berühmten Ramanujan-Geschichte Taxicab-Nummern genannt. Die kleinsten ganzen Zahlen, die als Summe von Würfeln von ganzen Zahlen auf sieben verschiedenen Wegen ausgedrückt werden können, ist derzeit unbekannt. Schreiben Sie ein Programm Taxicab. java, das in einem Befehlszeilenparameter N liest und alle nicht trivialen Lösungen eines 3 b 3 c 3 d 3 ausgibt, so dass a, b, c und d kleiner oder gleich N sind Zahlentheorie. Finden Sie alle Lösungen für die Gleichung a 2b 2 3c 3 4d 4, für die a, b, c und d kleiner als 100.000 sind. Hinweis. Verwenden Sie einen minimalen Haufen und einen maximalen Haufen. Interruptbehandlung. Bei der Programmierung eines Echtzeitsystems, das unterbrochen werden kann (z. B. durch einen Mausklick oder eine drahtlose Verbindung), ist es notwendig, sofort auf die Interrupts zu achten, bevor die laufende Aktivität fortgesetzt wird. Wenn die Interrupts in derselben Reihenfolge behandelt werden sollen, in der sie ankommen, dann ist eine FIFO-Warteschlange die geeignete Datenstruktur. Wenn jedoch unterschiedliche Interrupts unterschiedliche Prioritäten (z. B.) haben, dann benötigen wir eine Prioritätswarteschlange. Simulation von Warteschlangennetzwerken. MM1-Warteschlange für doppelte parallele Warteschlangen usw. Schwierig, komplexe Warteschlangen-Netzwerke mathematisch zu analysieren. Verwenden Sie stattdessen Simulation, um die Verteilung von Wartezeiten usw. zu verteilen. Benötigen Sie eine Prioritätswarteschlange, um zu bestimmen, welches Ereignis als nächstes zu verarbeiten ist. Zipf Verteilung. Verwenden Sie das Ergebnis der vorhergehenden Übung (en), um aus der Zipfian-Verteilung mit den Parametern s und N abzutasten. Die Verteilung kann ganzzahlige Werte von 1 bis N annehmen und nimmt den Wert k mit der Wahrscheinlichkeit 1ks sum (i 1 bis N) 1is an . Beispiel: Wörter in Shakespeares spielen Hamlet mit s etwa gleich 1. Random-Prozess. Beginnen Sie mit N Bins, jeweils bestehend aus einer Kugel. Wählen Sie nach dem Zufallsprinzip eine der N Kugeln aus und bewegen Sie den Ball so zufällig in einen Behälter, dass die Wahrscheinlichkeit, dass eine Kugel in einen Behälter mit m Kugeln gelegt wird, mN ist. Was ist die Verteilung der Kugeln, die nach vielen Iterationen resultiert Verwenden Sie die zufällige Stichprobenmethode, die oben beschrieben wurde, um die Simulation effizient zu machen. Nächste Nachbarn. Gegebene N Vektoren x 1. X 2. X N der Länge M und einem anderen Vektor x der gleichen Länge, finden Sie die 20 Vektoren, die am nächsten zu x sind. Kreis auf einem Stück Papier gezeichnet. Schreiben Sie ein Programm, um den Radius eines Kreises zu finden, zentriert auf dem Ursprung, der 32 Punkte mit ganzzahligen x - und y-Koordinaten berührt. Hinweis: Suchen Sie nach einer Zahl, die sich als Summe aus zwei Quadraten auf verschiedene Weise ausdrücken lässt. Antwort: Es gibt zwei pythagoreische Tripel mit Hypotenuse 25: 152 202 252, 72 242 252 mit 20 solcher Gitterpunkte gibt es 22 verschiedene Pythagoreische Tripel mit Hypotenuse 5,525, was zu 180 Gitterpunkten führt. 27.625 ist der kleinste Radius, der mehr als 64 berührt. 154.136.450 hat 35 pythagoreische Tripel. Vollkommene Kräfte. Schreiben Sie ein Programm PerfectPower. java, um alle perfekten Potenzen auszudrucken, die als 64-Bit lange Integer dargestellt werden können: 4, 8, 9, 16, 25, 27. Eine perfekte Power ist eine Zahl, die als ab für ganze Zahlen geschrieben werden kann Und b ge 2. Gleitpunktzusätze. Addieren Sie N Gleitkommazahlen, vermeiden Sie Rundungsfehler. Löschen Sie kleinste zwei: addieren Sie zwei gegenseitig und reinsert. First-fit für Abfalleimer. 1710 OPT 2, 119 OPT 4 (abnehmend). Verwenden Sie max Turnierbaum, in dem Spieler sind N Bins und Wert verfügbar Kapazität. Stapel mit minmax. Entwerfen Sie einen Datentyp, der push, pop, size, min und max unterstützt (wobei min und max die minimalen und maximalen Elemente auf dem Stack sind). Alle Operationen sollten im schlimmsten Fall eine konstante Zeit in Anspruch nehmen. Hinweis: Ordnen Sie jedem Stapeleintrag die minimalen und maximalen Gegenstände zu, die sich aktuell auf dem Stapel befinden. Warteschlange mit minmax. Entwerfen Sie einen Datentyp, der enqueue, dequeue, size, min und max unterstützt (wobei min und max die minimalen und maximalen Elemente in der Warteschlange sind). Alle Operationen sollten eine konstante Amortisationszeit einnehmen. Hinweis: führen Sie die vorherige Übung durch und simulieren Sie eine Warteschlange mit zwei Stapeln. 2i 5j. Nummern der Form 2i 5j in aufsteigender Reihenfolge ausgeben. Min-Max-Heap. Entwerfen Sie eine Datenstruktur, die min und max in konstanter Zeit unterstützt, einfügen, löschen min und löschen Sie max in logarithmischer Zeit, indem Sie die Elemente in ein einzelnes Array der Größe N mit den folgenden Eigenschaften setzen: Das Array stellt einen vollständigen binären Baum dar. Der Schlüssel in einem Knoten auf einer ebenen Ebene ist kleiner als (oder gleich) der Schlüssel in seinem Teilbaum der Schlüssel in einem Knoten auf einer ungeraden Ebene ist größer als (oder gleich) die Tasten in seinem Teilbaum. Beachten Sie, dass der Maximalwert an der Wurzel gespeichert wird und der Minimalwert in einem der Wurzelkinder gespeichert wird. Min-Max Heaps und Generalized Priority Queues Bereich Mindest-Abfrage. Bei einer Sequenz von N Elementen ist eine Bereichsminimalabfrage von Index i bis j der Index der minimalen Position zwischen i und j. Entwerfen einer Datenstruktur, die die Folge von N Elementen in linearer Zeit vorverarbeitet, um Bereichsminimalabfragen in logarithmischer Zeit zu unterstützen. Beweisen Sie, dass ein vollständiger Binärbaum mit N Knoten genau N2-Blattknoten (Knoten ohne Kinder) hat. Maximale Prioritätswarteschlange mit min. Was ist die Reihenfolge des Wachstums der Laufzeit, um einen minimalen Schlüssel in einem maximal-orientierten binären Heap zu finden. Lösung. Linearmdasht der minimale Schlüssel in irgendeinem der Decke (N2) Blattknoten sein könnte. Maximale Prioritätswarteschlange mit min. Entwerfen Sie einen Datentyp, der insert und remove-the-maximum in logarithmischer Zeit zusammen mit sowohl max als auch min in konstanter Zeit unterstützt. Lösung. Erstellen Sie einen max-orientierten Binärhaufen und speichern Sie den minimalen Schlüssel, der so weit eingefügt wird (der nie erhöht wird, wenn dieser Heap leer wird). Kth größten Element größer als x. Wenn ein maximal orientierter binärer Haufen gegeben ist, entwerfe einen Algorithmus, um zu bestimmen, ob das kth größte Element größer als oder gleich x ist. Ihr Algorithmus sollte in der Zeit proportional zu k laufen. Lösung. Wenn der Schlüssel im Knoten größer oder gleich x ist, rekursiv sowohl den linken Teilbaum als auch den rechten Teilbaum durchsuchen. Stopp, wenn die Anzahl der untersuchten Knoten gleich k ist (die Antwort ist ja) oder es gibt keine weiteren Knoten zu erforschen (nein). Kth kleinste Element in einem min-orientierten binären Heap. Entwerfen Sie einen k-log-k-Algorithmus, um das k-kleinste Element in einem min-orientierten binären Haufen H zu finden, der N Elemente enthält. Lösung. Erstellen Sie einen neuen min-orientierten Haufen H. Wir werden H nicht modifizieren. Fügen Sie die Wurzel von H in H zusammen mit seinem Heap-Index 1 ein. Lösen Sie nun wiederholt das minimale Element x in H und legen Sie in H die beiden Kinder von x aus H ein Das aus H gelöste k-te Element ist das k-kleinste Element in H. Randomisierte Warteschlange. Implementieren Sie eine RandomQueue, so dass jede Operation garantiert maximal logarithmische Zeit zu nehmen. Hinweis. Kann nicht verdoppeln Anordnung. Keine einfache Möglichkeit, mit verknüpften Listen zu lokalisieren ein zufälliges Element in O (1) Zeit. Verwenden Sie stattdessen einen vollständigen Binärbaum mit expliziten Verknüpfungen. FIFO-Warteschlange mit zufälliger Löschung. Implementieren Sie einen Datentyp, der die folgenden Operationen unterstützt: fügen Sie ein Element ein. Löschen Sie das Element, das zuletzt hinzugefügt wurde. Und löschen Sie ein zufälliges Element. Jede Operation sollte (höchstens) logarithmische Zeit im schlimmsten Fall. Lösung. Verwenden Sie einen vollständigen Binärbaum mit expliziten Verknüpfungen, weisen Sie die lange Integer-Priorität i dem i-ten Element zu, das der Datenstruktur hinzugefügt wird. Top k Summen von zwei sortierten Arrays. Gegeben sind zwei sortierte Arrays a und b, jede der Länge N, die größten k Summen der Form ai bj. Hinweis. Mit einer Prioritätswarteschlange (ähnlich dem Taxicab-Problem) können Sie einen O (k log N) - Algorithmus erreichen. Überraschenderweise ist es möglich, dies in O (k) Zeit zu tun, aber der Algorithmus ist kompliziert. Empirische Analyse des Haufenbaus. Empirisch vergleichen Sie die linear-time-bottom-up Heap-Konstruktion gegenüber der naiven linearithmischen Zeit-Top-down-Heap-Konstruktion. Seien Sie sicher, dass es über eine Reihe von Werten von N. LaMarca und Ladner berichten, dass aufgrund der Cache-Lokalität, kann der naive Algorithmus in der Praxis besser als die klügeren Ansatz für große Werte von N (wenn der Haufen nicht mehr passt in der Cache), obwohl letztere viel weniger Vergleiche und Austausch durchführt. Empirische Analyse von Mehrfachhaufen. Empirisch vergleichen Sie die Leistung von 2- 4- und 8-Wege-Haufen. LaMarca und Ladner schlagen mehrere Optimierungen vor, unter Berücksichtigung von Caching-Effekten. Empirische Analyse der Heapsort. Empirisch vergleichen Sie die Leistung von 2- 4- und 8-Wege-Heapsort. LaMarca und Ladner schlagen mehrere Optimierungen vor, unter Berücksichtigung von Caching-Effekten. Ihre Daten zeigen, dass eine optimierte (und abgestimmte) 8-Wege-Heapsort doppelt so schnell sein kann wie die klassische Heapsort. Heapify durch Einfügungen. Nehmen Sie an, dass Sie ein Binärhaufen auf N Tasten durch wiederholtes Einfügen der nächsten Taste in den binären Heap. Zeigen Sie, dass die Gesamtzahl der Vergleiche höchstens die Antwort ist. Die Anzahl der Vergleiche beträgt höchstens lg 1 lg 2. Lg N lg (N) N lg N. Untere Schranke heapify. (Gonnet und Munro) Zeigen Sie, dass jeder vergleichbasierte Algorithmus für den Aufbau eines binären Heaps auf N Schlüssel mindestens 1,3644 N im schlimmsten Fall benötigt. Antworten . Verwenden Sie ein informationstheoretisches Argument, ala Sortierung untere Schranke. Es gibt N mögliche Haufen (Permutation der N ganzen Zahlen) auf N verschiedenen Schlüsseln, aber es gibt viele Haufen, die der gleichen Anordnung entsprechen. Beispielsweise gibt es zwei Heaps (c a b und c b a), die den 3 Elementen entsprechen. A4.2 Sortieren und Suchen Das Sortierproblem besteht darin, ein Array von Elementen in aufsteigender Reihenfolge neu anzuordnen. In diesem Abschnitt werden wir zwei klassische Algorithmen zur Sortierung und Suche nach mdashbinärer Suche und Mergesort zusammen mit verschiedenen Anwendungen betrachten, bei denen ihre Effizienz eine entscheidende Rolle spielt. Binärsuche. Im Spiel von zwanzig Fragen ist es Ihre Aufgabe, den Wert einer Geheimzahl zu erraten, die eine der n ganzen Zahlen zwischen 0 und n minus1 ist. Der Einfachheit halber nehmen wir an, dass n eine Potenz von 2 ist und dass die Fragen die Form haben, ist die Zahl größer oder gleich x Eine effektive Strategie besteht darin, ein Intervall zu pflegen, das die geheime Zahl enthält, raten Sie die Zahl in der Mitte Des Intervalls und verwenden Sie dann die Antwort, um die Intervallgröße zu halbieren. Questions. java implementiert diese Strategie. Es ist ein Beispiel für das allgemeine Problemlösungsverfahren, bekannt als binäre Suche. Analyse der Laufzeit. Da die Größe des Intervalls bei jeder Iteration um einen Faktor 2 abnimmt (und der Basisfall bei n 1 erreicht wird), beträgt die Laufzeit der binären Suche lg n. Linearndashlogarithm chasm. Die Alternative zur Verwendung der binären Suche besteht darin, 0, dann 1, dann 2, dann 3 und so weiter zu erraten, bis die geheime Zahl getroffen wird. Wir verweisen auf einen solchen Algorithmus wie einen Brute-Force-Algorithmus: Es scheint, den Job zu erledigen, aber ohne viel Rücksicht auf die Kosten (die es verhindern könnten, dass es tatsächlich die Arbeit für große Probleme). Im schlimmsten Fall kann die Laufzeit bis zu n betragen. Binärdarstellung. Wenn Sie auf Binary. java zurückblicken. Werden Sie erkennen, dass die binäre Suche ist fast die gleiche Berechnung wie die Umwandlung einer Zahl in binäre Jede Vermutung bestimmt ein Bit der Antwort. Wenn z. B. die Zahl 77 ist, ergibt die Folge der Antworten nein ja ja nein nein ja nein ergibt sofort 1001101, die binäre Darstellung von 77. Invertieren einer zunehmenden Funktion f (x). Bei gegebenem Wert y. Unsere Aufgabe ist es, einen Wert x mit f (x) y zu finden. (Hi minus lo) 2 Basisfall: Wenn (hi minus lo) kleiner als delta ist, dann kehren Sie mittel als Schätzung zurück Von x Rekursiver Schritt: Andernfalls testen Sie, ob f (mittel) y. Wenn ja, suchen Sie nach x in (lo. Mid), wenn nicht nach x suchen in (midi hi). Die Methode inverseCDF () in Gaussian. java implementiert diese Strategie für die Gaußsche kumulative Dichtefunktion Phi. In diesem Zusammenhang wird die Binärsuche oft als Bisektionssuche bezeichnet. Binäre Suche in einem sortierten Array. Eine der wichtigsten Verwendungen der binären Suche besteht darin, ein Element in einem sortierten Array zu finden. Sehen Sie sich dazu das Array-Element in der Mitte an. Wenn es das Element, das Sie suchen, sind Sie sonst getan, beseitigen Sie entweder das Subarray vor oder nach dem mittleren Element aus Betrachtung und Wiederholung. BinarySearch. java ist eine Implementierung dieses Algorithmus. Sortieren durch Einfügen. Einfügungssortierung ist ein Brute-Force-Sortieralgorithmus, der auf einer einfachen Methode basiert, die die Leute häufig benutzen, um Hände von Spielkarten zu arrangieren: Betrachten Sie die Karten jeweils einzeln und fügen Sie jede an ihren richtigen Platz unter den bereits Betrachteten ein (halten sie sortiert) . Der folgende Code imitiert diesen Prozess in einer Java-Methode, die Strings in einem Array sortiert: Am Anfang jeder Iteration der äußeren for-Schleife befinden sich die ersten i-Elemente in dem Array in sortierter Reihenfolge, wobei die innere for-Schleife ai in ihre richtige Position bewegt In dem Array, indem es mit jedem großen Wert nach links bewegt wird, indem er sich von rechts nach links bewegt, bis er seine richtige Position erreicht. Hier ist ein Beispiel, wenn i 6 ist. Dieser Vorgang wird zuerst mit i gleich 1 ausgeführt. Dann 2. Dann 3. Und so weiter, wie in der folgenden Spur dargestellt. Analyse der Laufzeit. Die innere Schleife des Insertions-Sortiercodes befindet sich innerhalb einer doppelten verschachtelten for-Schleife, was darauf hindeutet, dass die Laufzeit quadratisch ist, aber wir können diese Schlussfolgerung aufgrund der Pause nicht sofort ziehen. I'm besten fall. Wenn das Eingangsarray bereits in der sortierten Reihenfolge ist, ist die Gesamtzahl der Vergleiche in n und die Laufzeit linear. Schlimmsten Fall. Wenn der Eingang umgekehrt sortiert ist, ist die Anzahl der Vergleiche 12 n 2 und die Laufzeit ist quadratisch. Durchschnittlicher Fall. Wenn die Eingabe zufällig geordnet ist, ist die erwartete Anzahl von Vergleichen 14 n & sub2; und die Laufzeit ist quadratisch. Sortierung anderer Datentypen. Wir wollen alle Arten von Daten sortieren können, nicht nur Strings. Für die Sortierung von Objekten in einem Array müssen wir nur annehmen, dass wir zwei Elemente vergleichen können, um zu sehen, ob die erste größer als, kleiner oder gleich der zweiten ist. Java bietet die Vergleichsschnittstelle für diesen Zweck. Insertion. java implementiert insertion sort, so dass es Arrays von vergleichbaren Objekten sortiert. Empirische Analyse. InsertionTest. java testet unsere Hypothese, dass Insertionsart quadratisch für zufällig geordnete Arrays ist. Zusammenführen, sortieren. Um eine schnellere Sortiermethode zu entwickeln, verwenden wir einen Divide-and-Conquer-Ansatz für das Algorithmusdesign, das jeder Programmierer verstehen muss. Um ein Array zusammenzuführen, teilen wir es in zwei Hälften auf, sortieren die beiden Hälften unabhängig voneinander und fügen dann die Ergebnisse zusammen, um das gesamte Array zu sortieren. Zu sortieren, hi). Verwenden wir die folgende rekursive Strategie: Basisfall. Wenn die Subarraylänge 0 oder 1 ist, ist sie bereits sortiert. Verkleinerungsschritt. Andernfalls berechnen Sie den Mittelwert lo (hi - lo) 2. Rekursiv sortieren die beiden Subarrays alo, mid) und inmitten, hi). Und fügen sie zusammen, um ein sortiertes Ergebnis zu erzeugen. Merge. java ist eine Implementierung dieser Strategie. Hier ist eine Spur des Inhalts des Arrays während eines Merge. Analyse der Laufzeit. Im schlimmsten Fall stellt mergesort zwischen n lg n und die Laufzeit linearithmisch dar. Siehe das Buch für Details. Quadratisch-achlinearithmischer Abgrund. Der Unterschied zwischen n 2 und n lg n macht einen großen Unterschied in der Praxis. Divide-and-conquer-Algorithmen. Die gleiche grundlegende Ansatz ist wirksam für viele wichtige Probleme, wie Sie lernen, wenn Sie einen Kurs über Algorithmus-Design zu nehmen. Reduzierung der Sortierung. Ein Problem A reduziert sich auf ein Problem B, wenn wir eine Lösung für B verwenden können, um A zu lösen. Betrachten wir beispielsweise das Problem der Bestimmung, ob die Elemente in einem Array alle verschieden sind. Dieses Problem reduziert sich auf Sortierung, weil wir das Array sortieren können, um einen linearen Durchlauf durch das sortierte Array zu erstellen, um zu überprüfen, ob ein Eintrag gleich dem nächsten ist (wenn nicht, sind die Elemente alle unterschiedlich.) Häufigkeit zählt. FrequencyCount. java liest eine Folge von Zeichenketten aus der Standard-Eingabe und druckt dann eine Tabelle der verschiedenen gefundenen Werte und die Anzahl der gefundenen Male in absteigender Reihenfolge der Frequenzen. Das schaffen wir durch zwei Sorten. Berechnung der Frequenzen. Unser erster Schritt ist, die Saiten auf Standard-Eingang zu sortieren. In diesem Fall sind wir nicht so sehr daran interessiert, dass die Saiten sortiert werden, sondern in der Tatsache, dass die Sortierung gleiche Saiten zusammenführt. Wenn die Eingabe dann ist das Ergebnis der Sortierung ist mit gleichen Zeichenfolgen wie die drei Vorkommen, um zusammen in der Array. Nun, mit gleichen Strings alle zusammen in der Array, können wir einen einzigen Durchlauf durch das Array, um alle Frequenzen zu berechnen. Der Counter. java-Datentyp, den wir in Abschnitt 3.3 betrachtet haben, ist das perfekte Werkzeug für den Job. Sortierung der Frequenzen. Als nächstes sortieren wir die Gegenobjekte. Wir können dies in Client-Code ohne besondere Vorkehrungen tun, weil Counter implementiert die Vergleichbare Schnittstelle. Zipfs Gesetz. Die Anwendung, die in FrequencyCount. java hervorgehoben wird, ist elementare linguistische Analyse: welche Wörter am häufigsten in einem Text erscheinen Ein Phänomen, das als Zipfs-Gesetz bekannt ist, sagt, dass die Häufigkeit des i-ten häufigsten Wortes in einem Text von m verschiedenen Wörtern proportional zu 1 i ist. Schreiben Sie einen Filter Dedup. java, der Strings von der Standardeingabe liest und sie auf der Standardausgabe druckt, wobei alle Duplikate entfernt (in der sortierten Reihenfolge) sind. Kreative Übungen Diese Liste der Übungen soll Ihnen dabei helfen, schnelle Lösungen für typische Probleme zu entwickeln. Denken Sie über die Verwendung von binären Suche, Mergesort, oder die Ausarbeitung Ihrer eigenen Divide-and-conquer-Algorithmus. Implementieren und testen Sie Ihren Algorithmus. Integer-Sortierung. Schreiben Sie einen linearen Filter IntegerSort. java, der von einer Standard-Eingabe eine Folge von ganzen Zahlen liest, die zwischen 0 und 99 liegen, und druckt auf die Standardausgabe die gleichen Ganzzahlen in sortierter Reihenfolge aus. Zum Beispiel mit der Eingabe-Sequenz präsentiert Ihr Programm sollte die Ausgabe-Sequenz ausgeben Drei Summe. Angenommen, ein Array von n ganzen Zahlen, erstellen Sie einen Algorithmus, um festzustellen, ob alle drei von ihnen auf 0 summieren. Die Reihenfolge des Wachstums der Laufzeit Ihres Programms sollte n 2 log n sein. Zusätzliche Gutschrift. Entwickeln Sie ein Programm, das das Problem in quadratischer Zeit löst. Lösung. ThreeSumDeluxe. java. Schnelle Sorte. Schreiben Sie ein rekursives Programm Quick. java, das ein Array von vergleichbaren Objekten sortiert, indem Sie als Subroutine den Partitionierungsalgorithmus verwenden, der in der vorherigen Übung beschrieben wurde: Zuerst wählen Sie ein zufälliges Element v als Partitionierungselement aus. Als nächstes wird das Array in ein linkes Teilarray unterteilt, das alle Elemente kleiner als v enthält, gefolgt von einem mittleren Teilarray, das alle Elemente gleich v enthält, gefolgt von einem rechten Teilarray, das alle Elemente enthält, die größer als v sind. Schließlich rekursiv die linken und rechten Teilarrays sortieren. Reverse-Domäne. Schreiben Sie ein Programm, um in einer Liste von Domain-Namen aus der Standard-Eingabe zu lesen, und drucken Sie die Reverse-Domain-Namen in sortierter Reihenfolge. Zum Beispiel ist die reverse Domäne von cs. princeton. edu edu. princeton. cs. Diese Berechnung ist für die Web-Log-Analyse nützlich. Erstellen Sie dazu einen Datentyp Domain. java, der die Vergleichsschnittstelle implementiert, indem Sie die Reverse-Domain-Namenreihenfolge verwenden. Lokales Minimum in einem Array. Wenn ein Array a von n reellen Zahlen vorliegt, entwerfe einen logarithmischen Zeitalgorithmus, um ein lokales Minimum zu finden (ein Index i, so dass sowohl ai-1 T, C G. Beispielsweise sind ATTTCGG und CCGAAAT umgekehrte Komplemente von einander Um die Suche in einer Datenbank von DNA-Strings zu erleichtern, brauchen wir einen Ort, um sie zu brechen, um eine lineare Zeichenfolge zu bilden. Eine natürliche Wahl ist der Ort, der Verlässt die lexikographisch kleinste Zeichenkette und legt einen Algorithmus zur Berechnung dieser kanonischen Repräsentation der kreisförmigen Zeichenkette fest Hint. suffix sort Finden Sie alle Übereinstimmungen Angesichts einer Textfolge finden Sie alle Übereinstimmungen der Abfragezeichenfolge Hinweis: Kombinieren Sie die Suffix-Sortierung und die binäre Suche Wiederholt substring mit weniger Speicher. Statt der Verwendung eines Arrays von substrings, wo suffixesi bezieht sich auf die ith sortierte Suffix, pflegen ein Array von ganzen Zahlen, so dass indexi bezieht sich auf den Offset des i-ten sortierten Suffix. Um Vergleich der Teilstrings durch ein indexi und b dargestellt Indexj, vergleichen Sie den Charakter s. charAt (a) gegen s. charAt (b). S. charAt (a1) gegen s. charAt (b1). und so weiter. Wie viel Speicher Sie speichern Ist Ihr Programm schneller Leerlaufzeit. Angenommen, eine parallele Maschine verarbeitet n Jobs. Der Job j wird von s j bis t j verarbeitet. Angesichts der Liste der Start - und Endzeiten finden Sie das größte Intervall, in dem die Maschine im Leerlauf ist. Finden Sie das größte Intervall, in dem die Maschine nicht leer ist. Lokales Minimum einer Matrix. Gegeben sei ein N-durch-N-Array a von N 2 verschiedenen Ganzzahlen, entwerfe einen O (N) - Algorithmus, um ein lokales Minimum zu finden. Ein Paar von Indizes i und j mit aij xj und yi yj. Ein Maxima ist ein Punkt, der von keinem anderen Punkt im Satz dominiert wird. Entwickeln Sie einen O (n log n) - Algorithmus, um alle Maxima zu finden. Anwendung: auf der x-Achse ist die Raumeffizienz, auf der y-Achse ist die Zeit-Effizienz. Maxima sind nützliche Algorithmen. Hinweis: Aufsteigend nach x-Koordinaten-Scan von rechts nach links sortieren, den bisher höchsten y-Wert aufzeichnen und als Maxima markieren. Zusammengesetzte Wörter. Lesen Sie in einer Liste von Wörtern aus der Standard-Eingabe, und drucken Sie alle zwei Wort zusammengesetzte Wörter. Wenn nach. Dachte. Und nachgedacht sind in der Liste, dann ist nachträglich ein zusammengesetztes Wort. Hinweis: Die Komponenten im zusammengesetzten Wort müssen nicht die gleiche Länge haben. Smiths Regel. Im Supply Chain Management stellt sich folgendes Problem. Sie haben eine Reihe von Jobs auf einem einzigen Computer zu planen. (Geben Sie Beispiel.) Job j erfordert pj Einheiten der Bearbeitungszeit. Job j hat ein positives Gewicht wj, das seine relative Wichtigkeit darstellt - denken Sie es als die Inventurkosten für die Lagerung der Rohstoffe für Job j für 1 Einheit der Zeit. Wenn der Job j zum Zeitpunkt t bearbeitet wird, kostet er t wj Dollar. Das Ziel ist, die Aufträge so zu sequenzieren, dass die Summe der gewichteten Fertigstellungszeiten jedes Auftrags minimiert wird. Schreiben Sie ein Programm SmithsRule. java, das in einem Befehlszeilenparameter N und einer Liste von N Aufträgen liest, die durch ihre Verarbeitungszeit pj und ihr Gewicht wj spezifiziert sind, und geben eine optimale Sequenz aus, in der ihre Jobs verarbeitet werden sollen. Hinweis: Verwenden Sie Smiths Regel. Planen Sie die Aufträge in der Reihenfolge ihres Verhältnisses von Bearbeitungszeit zu Gewicht. Diese gierige Regel erweist sich als optimal. Summe aus vier Primzahlen. Die Goldbach-Vermutung sagt, daß alle positiven ganzen Zahlen größer als 2 als Summe von zwei Primzahlen ausgedrückt werden können. Wenn man einen Eingabeparameter N (ungerade oder gerade) nennt, wird N als die Summe von vier Primzahlen (nicht unbedingt unterschiedlich) ausgedrückt oder berichtet, dass dies unmöglich ist. Um Ihren Algorithmus schnell für große N zu machen, führen Sie die folgenden Schritte aus: Berechnen Sie alle Primzahlen kleiner als N mit dem Sieb von Eratosthenes. Tabulieren Sie eine Liste von Summen zweier Primzahlen. Sortieren Sie die Liste. Prüfen Sie, ob es zwei Nummern in der Liste gibt, die zu N addieren. Wenn ja, drucken Sie die entsprechenden vier Primzahlen aus. Typing Affen und Macht Gesetze. (Michael Mitzenmacher) Angenommen, ein typisierender Affe erzeugt zufällige Wörter durch Anfügen von jeweils 26 möglichen Buchstaben mit Wahrscheinlichkeit p an das aktuelle Wort und beendet das Wort mit Wahrscheinlichkeit 1 - 26p. Schreiben Sie ein Programm, um das Frequenzspektrum der produzierten Wörter abzuschätzen. Typing Affen und Macht Gesetze. Wiederholen Sie die vorherige Übung, aber nehmen Sie an, dass die Buchstaben a-z proportional zu den folgenden Wahrscheinlichkeiten, die typisch für englische Text sind. Die while-Schleife invariante sagt top bot 2. Dies impliziert bot Zwei Summe bis x. Bei einer sortierten Liste von N Ganzzahlen und einer Zielinteger x, bestimmen Sie in O (N) Zeit, ob es zwei, die Summe genau x. Hinweis. Einen Index lo 0 und hi N-1 beibehalten und alo ahi berechnen. Wenn die Summe gleich x ist, sind Sie fertig, wenn die Summe kleiner ist als x, Dekrementierung hi, wenn die Summe größer als x, Inkrement lo ist. Seien Sie vorsichtig, wenn eine (oder mehrere) der ganzen Zahlen 0 ist. Null einer monotonen Funktion. Sei f eine monoton wachsende Funktion mit f (0) 0. Finden Sie die kleinste ganze Zahl i mit f (i) 0. Entwerfen Sie einen Algorithmus, der O (log N) - Aufrufe nach f () macht. Hinweis. Vorausgesetzt, wir kennen N, marinieren ein Intervall lo, hi, so dass flo 0 und gelten binäre Suche. Wenn wir N nicht kennen, wiederholen Sie wiederholt f (1), f (2), f (4), f (8), f (16) und so weiter, bis Sie einen Wert von N mit f (N) 0 finden Bitonic max. Sei a ein Array, das zunehmend anfängt, ein Maximum erreicht und dann abnimmt. Entwerfen Sie einen O (log N) - Algorithmus, um den Index des Maximalwerts zu finden. Bitonische Suche. Ein Array ist bitonisch, wenn es aus einer ansteigenden Folge von ganzen Zahlen besteht, gefolgt von einer abnehmenden Folge von ganzen Zahlen. Angenommen, ein bitonisches Array a von N verschiedenen Ganzzahlen, beschreiben, wie zu bestimmen, ob eine gegebene Ganzzahl im Array in O (log N) Schritte ist. Hinweis: Finden Sie die maximale, dann binäre Suche in jedem Stück. Median in zwei sortierten Arrays. Bei zwei sortierten Arrays der Größe N 1 und N 2. Finden Sie den Median aller Elemente in O (log N) Zeit mit N N 1 N 2. Hinweis. Entwurf eines allgemeineren Algorithmus, der das kth größte Element für jedes k findet. Berechnen Sie das mittlere Element in der großen der beiden Listen und werfen Sie mindestens 14 der Elemente und recur. Element Unterscheidbarkeit. Geben Sie ein Array von N langen Ganzzahlen an, erstellen Sie einen O (N log N) Algorithmus, um festzustellen, ob zwei gleich sind. Hinweis. Sortierung bringt gleiche Werte zusammen. Anzahl duplizieren. Geben Sie ein sortiertes Array von N Elementen, möglicherweise mit Duplikaten, den Index des ersten und letzten Vorkommens von k in O (log N) Zeit. Geben Sie ein sortiertes Array von N Elementen, möglicherweise mit Duplikaten, die Anzahl der Vorkommen von Element k in O (log N) Zeit. Hinweis. Binärsuche ändern. Gemeinsames Element. Schreiben Sie eine statische Methode, die als Argument drei Arrays von Zeichenfolgen verwendet, bestimmt, ob es eine Zeichenfolge gibt, die allen drei Arrays gemeinsam ist, und wenn ja, gibt eine solche Zeichenfolge zurück. Die Laufzeit Ihrer Methode sollte linearithmisch in der Gesamtzahl der Zeichenfolgen sein. Hinweis. Sortieren Sie jede der drei Listen, dann beschreiben, wie ein 3-Wege-Merge zu tun. Längste wiederholte Teilzeichenfolge. Schreiben Sie ein Programm LRS. java, um die längste wiederholte Teilzeichenfolge in einem String zu finden. Finden Sie die längste wiederholte Teilzeichenfolge in Ihrem Lieblingsbuch. Fügen Sie Code zu LRS. java hinzu, damit es Indizes in der ursprünglichen Zeichenfolge druckt, wo die längste wiederholte Teilzeichenfolge auftritt. Längste gemeinsame Teilkette. Schreiben Sie eine statische Methode, die den längsten gemeinsamen Teilstring von zwei gegebenen Strings s und t findet. Hinweis. Suffix sortiert jede Zeichenfolge. Fügen Sie dann die beiden sortierten Suffixe zusammen. Längste wiederholte, nicht überlappende Zeichenfolge. Ändern Sie LRS. java, um den längsten wiederholten Teilstring zu finden, der nicht überlappt. Reimende Worte. Schreiben Sie ein Programm Rhymer. java, das eine Liste tabelliert, die Sie verwenden können, um Wörter zu finden, die reimen. Verwenden Sie den folgenden Ansatz: Lesen Sie in einem Wörterbuch von Wörtern in einem Array von Zeichenfolgen. Umkehren Sie die Buchstaben in jedem Wort (confound wird zum Beispiel dnuofnoc.). Sortieren Sie das resultierende Array. Umkehren Sie die Buchstaben in jedem Wort zurück zu ihrer ursprünglichen Reihenfolge. Zum Beispiel ist confound an Worte wie astound und umgeben in der resultierenden Liste angrenzend. Wissenschaftliches Beispiel der Sortierung. Google zeigt Suchergebnisse in absteigender Reihenfolge an, ein Tabellenblatt zeigt nach einem bestimmten Feld sortierte Spalten an, Matlab sortiert die reellen Eigenwerte einer symmetrischen Matrix in absteigender Reihenfolge. Die Sortierung entsteht auch als kritische Unterroutine in vielen Anwendungen, die mit der Sortierung überhaupt nichts zu tun haben: Datenkomprimierung (siehe die Burrows-Wheeler-Programmierzuweisung), Computergrafik (konvexe Hülle, engste Paare), Computerbiologie (längste gemeinsame (Kendalls tau distance), historisch gesehen, war die Sortierung am wichtigsten für kommerzielle Anwendungen, aber auch Sortierung. Deutsch: www. tab. fzk. de/de/projekt/zusammenf...ng/ab117.htm Spielt eine wichtige Rolle in der wissenschaftlichen Computerinfrastruktur. NASA und die Flüssigkeiten Mechanik Gemeinde verwenden Sortierung, um Probleme in verdünnter Strömung zu studieren diese Kollision Erkennung Probleme sind besonders herausfordernd, da sie beinhalten zehn Milliarden von Partikeln und können nur auf Supercomputern parallel gelöst werden. Ähnliche Sortierungstechniken werden in einigen schnellen N-Körper-Simulationscodes verwendet. Eine weitere wichtige wissenschaftliche Anwendung der Sortierung ist die Lastverteilung der Prozessoren eines parallelen Supercomputers. Die Wissenschaftler verlassen sich auf cleveren Sortier-Algorithmus, um Load-Balancing auf solchen Systemen durchzuführen. Zuletzt geändert am 11. November 2016. Copyright-Kopie 2000ndash2016 Robert Sedgewick und Kevin Wayne. Alle Rechte vorbehalten.

No comments:

Post a Comment