Aufgabe 10.6


So… Weihnachten vorbei! =)
Ich hab dann gleich mal ne blöde Frage… ne ziemlich peinlich-blöde:
PRIORITÄTSWarteschlange, wie soll die ihre Elemente speichern:

Soll z.B. enqueue(…) einfach nur ans Ende der Schlange ein Element anfügen ohne rücksicht auf die Priorität der bestehenden Elemente? Dann wäre die Reihenfolge der Elemente durcheinander und die Prioritäten könnten z.B. in folgender Reihenfolge in der Schlange vorkommen:
3–>6–>1–>3–>4–>2–>…

Oder sollen die Elemente schon beim Einfügen ihrer Reihenfolge nach sortiert und an der entsprechenden Stelle eingefügt werden? Dann wäre das Element mit der höchsten Priorität automatisch der Kopf und die Prioritäten wären absteigend sortiert… (Ich habe gelesen, dass die höchste priorität der kleinste Wert sein soll → http://de.wikipedia.org/wiki/Vorrangwarteschlange das steht da bei “Operationen” oO):
1–>2–>5–>6–>6–>8–>…

Bitte um Aufklärung. Thx schon mal! :slight_smile:


Wie du es speicherst und wann du sortierst bleibt dir überlassen. Entweder du sortierst beim Auslesen, womit du beim Einfügen machen kannst, was du willst oder du kannst schon beim Einfügen sortieren und beim Auslesen immer das am weitesten vorne stehende Element nehmen.
Hauptsache, die Elemente kommen nach Priorität und in der Reihenfolge wie sie auch reingeschrieben wurden wieder raus.


hmmmmm
und wie ist das jetzt mit der priorität? Kleinster Wert = höchste Priorität?

Ich glaub, ich sortiers gleich beim Einfügen, dann muss ich bei dequeue() nur jedesmal den Kopf wegnehmen laut Aufgabenstellung… :wink:

/**
* entfernt das Element mit der hoechsten Prioritaet, das schon am
* laengsten in der Warteschlage ist
* 
* @return liefert das entfernte Element
* @throws NoSuchElementException wenn die Schlange leer ist
*/

Ist doch egal welchen Wert du hast?
die Priorität ist wichtig nach der du sortierst und je höher deine Priorität desto höher sortierst dus halt ein.
Was nicht warum der Wert da von bedeutung sein sollte


Gemeint ist mit ziemlicher Sicherheit der Wert der Priorität. Priotät mit dem Integer ‘5’ hat entsprechend den Wert ‘5’ :wink:

Ist auf jedenfall nirgends angegeben … aber ich denke mal, dass etwas eine höhere Priorität hat, bei einem höheren Wert. Allerdings ist es unter Linux ja tatsächl. so, dass ein Prozess mit niedrigem Prozess Zahlenwert eine höhere Priorität hat (?) …wäre schreckl. da ich es andersrum gebaut habe.

Habe ich etwas übersehen, oder ist es tatsächl. nirgends angegeben ( und damit entsprechend egal ) ?


Naja n <= is glei durch > ersetzt das is nich das ding, aber was gewünscht is wäre schon gut zu wissen, aber wahrscheinlich wenns schon in WP steht wirds wohl je kleiner desto wichtiger sein.


Öh, ich hab das genau andersrum verstanden. Ich dachte, je größer der Integer, desto wichtiger.
Aber es steht wohl tatsächlich nirgendwo…


So hab ich’s auch verstanden. Folie 10-69 zeigt das meiner Meinung nach auch: Da zeigt „kopf“ auf das Element 100 und „ende“ auf das Element 80.


ja eben… deswegen hab ich das Thema hier noch mal angerissen. Ich denke, es wird egal sein (SOLLTE ES JEDENFALLS!), da es nicht genauer in der Aufgabenstellung spezifiziert war. Allerdings werden die Testcases dann natürlich bei der entsprechenden falschen Variante fehlschlagen, da z.B. ein front() einmal das Element mit dem geringsten Prioritätswert zurückgibt und bei der anderen Variante das Element mit dem höchsten Wert…

Ausserdem ist mir noch folgende Formulierung schleierhaft:
“Nur über diesen Iterator soll es möglich sein, beliebige Werte aus der Schlange zu löschen.”

Wofür bitte brauch ich denn dann dequeue() und vor allem dequeue(int prioritaet)?
Ich könnte höchstens in der remove()-Methode im Iterator dann dequeue(int prioritaet) aufrufen, was aber meiner meinung nach keinen Sinn macht. Denn wenn ich z.B. im Programm iterator().remove() [oder so ähnlich] aufrufe, dann kann ich da ja nicht die gewuenschte prioritaet direkt uebergeben, sondern muesste mich erst mit dem Iterator an das gewuenschte Element hinhangeln?!
Das würde einen völlig überflüssigen Mehraufwand bedeuten, was meiner Ansicht nach absolut sinnlos wäre.
Wie habt ihr denn das gelöst?

Ich wünsche euch nen guten Beschluss… fangt’s das neue Jährchen gut an! :wink:


hm

mit iterator.remove() kannste halt z.b. wenn du in der mitte 3 elemente mit prio 5 hast, das mittlere davon rauslöschen… mit dequeue kannste ja entweder alle mit 5 oder nur das 1. element löschen…


Ich wünsch einen guten start im neuen Jahr

Wert=Priorität => großer Wert=große Priorität (so wie in der Vorlesung)
Das Beispiel von holde wegen dem Löschen gefällt mir, da hab ich nix dazuzusagen. :wink:


Hier mal ein paar Testcases. Als Anhang gibts die Testcases zum Selbstprobieren :wink:
Habt ihr noch irgendwelche anderen Fälle beachtet?

--- Create queue ---
[ 
[ Empty: true, Size: 0, MaxPriority: -2147483648

--- Fill queue with some values ---
[ (Hallo|100)(Feueralarm|50)(Pupsen|1)
[ Empty: false, Size: 3, MaxPriority: 100, MaxPriorityValue: Hallo

--- Fill queue with other values ---
[ (Test|312)(Hallo|100)(Feueralarm|50)(Test|12)(Pupsen|1)(Minus|-20)
[ Empty: false, Size: 6, MaxPriority: 312, MaxPriorityValue: Test

--- Enqueue item with exisiting priority ---
[ (Test|312)(Hallo|100)(Kanu|100)(Feueralarm|50)(Test|12)(Pupsen|1)(Minus|-20)
[ Empty: false, Size: 7, MaxPriority: 312, MaxPriorityValue: Test

--- Dequeue some items ---
Dequeue: Test (312)
Dequeue: Hallo (100)
Dequeue: Kanu (100)
[ (Feueralarm|50)(Test|12)(Pupsen|1)(Minus|-20)
[ Empty: false, Size: 4, MaxPriority: 50, MaxPriorityValue: Feueralarm

--- Enqueue items with same priority ---
[ (Feueralarm|50)(Test|12)(Pupsen|1)(1|-13)(2|-13)(3|-13)(Minus|-20)
[ Empty: false, Size: 7, MaxPriority: 50, MaxPriorityValue: Feueralarm

--- Dequeue via priority ---
Dequeue 11: false
Dequeue -13: true
[ (Feueralarm|50)(Test|12)(Pupsen|1)(Minus|-20)
[ Empty: false, Size: 4, MaxPriority: 50, MaxPriorityValue: Feueralarm

--- Enqueue null ---
[ (null|7000)(Feueralarm|50)(Test|12)(Pupsen|1)(Minus|-20)
[ Empty: false, Size: 5, MaxPriority: 7000, MaxPriorityValue: null

--- Iterate through queue and test remove ---
Next: null
Removed!
Next: Feueralarm
Next: Test
Next: Pupsen
Removed!
java.lang.IllegalStateException
Next: Minus
Next: java.util.NoSuchElementException
[ (Feueralarm|50)(Test|12)(Minus|-20)
[ Empty: false, Size: 3, MaxPriority: 50, MaxPriorityValue: Feueralarm

--- Create another queue and fill with some values ---
[ (high|1000)(null|100)(20|20)(nix|-1000)
[ Empty: false, Size: 4, MaxPriority: 1000, MaxPriorityValue: high

--- Add queue 2 to queue 1 ---
Queue 1:
[ (high|1000)(null|100)(Feueralarm|50)(20|20)(Test|12)(Minus|-20)(nix|-1000)
[ Empty: false, Size: 7, MaxPriority: 1000, MaxPriorityValue: high
Queue 2:
[ (high|1000)(null|100)(20|20)(nix|-1000)
[ Empty: false, Size: 4, MaxPriority: 1000, MaxPriorityValue: high

--- Add null-queue to queue 1 ---
java.lang.IllegalArgumentException: Schlange must not be null.

--- Clear queue 1 ---
[ 
[ Empty: true, Size: 0, MaxPriority: -2147483648

--- Get front-item of empty queue ---
java.util.NoSuchElementException

--- Dequeue from empty queue ---
java.util.NoSuchElementException

Edit: Damit der Anhang funktioniert muss in der Warteschlange.java folgende Methode vorhanden sein:

	public String toString() {
		// Temporäre Variablen
		Iter iter = new Iter();
		PriorisiertesElement<WertType> item = null;
		String string = "[ ";
		// Alle Elemente durchgehen und in String schreiben
		while (iter.hasNext()) {
			item = iter.next();
			string = string + "(" + item.wert() + "|" + item.prioritaet() + ")";
		}
		// Eigenschaften der Schlange in String schreiben
		string = string + "\n[ Empty: " + empty() + ", Size: " + size + ", MaxPriority: " + maxPrioritaet();
		// Wenn die Schlange nicht leer ist, weitere Eigenschaften schreiben
		if (empty()) {
			string = string + "\n";
		} else {
			string = string + ", MaxPriorityValue: " + front() + "\n";
		}
		// String ausgeben
		return string;
	}

Attachment:
Program.java: https://fsi.cs.fau.de/unb-attachments/post_47266/Program.java


Hallo,

vielen Dank für die Veröffentlichung deiner Testcases.

Ich habe das ganze jetzt mal eingebaut, und komme soweit auch auf dein Ergebnis ( Bis auf die IllegalArgumentException; da kommt bei mir ein Nullpointer ). Deine toString musste ich übrigens etwas modifizieren, damit sie funktionierte.

Aus

Iter iter = new Iter();

musste ich

Iterator<PriorisiertesElement<WertType>> iter = iterator();

machen.

Hast du da irgendwas umgebaut ?

Ich hatte ebenfalls angedacht, mal nach einem Tausch von Testcases zu fragen, jedoch ist meine Schlange auf “Amateur-Art” getestet worden; sprich eine gigantische, alles andere als übersichtliche, main - Methode. Das wollte ich dann doch keinem antun :wink:


Hey, danke für den Hinweis. Sieht so wie dus hast schöner aus :wink:

Bei mir klappts aber auch mit iter = new Iter() weil mein Iterator so aussieht:

private class Iter implements Iterator<PriorisiertesElement<WertType>> {...}

Ja, NullPointerException ist da vllt sogar schöner :wink: Kann man sich drüber streiten ^^


Jein, an der Nullpointer bin ich nicht aktiv beteiligt, sie kommt mehr von selbst, das ist mein Problem dabei :wink:

Sobald versucht wird mit schlange.iterator() eine neue Iterator Instanz in enq.-all zu machen, wirft Java denk ich von sich aus die Nullpointer. Ich überlege, ob ich das irgendwie abfangen sollte … vielleicht einfach nur try catch rum und Methode beenden. Letztendlich hat sie ja dann ihre Aufgabe erledigt, Nichts wurde zur aktuellen Schlange hinzugefügt.

Den Iterator habe ich analog zur Vorlesung gestaltet.


Nein, ich würde das nicht abfangen. Für solche Fälle ist ja die NullPointerException da. :wink:


Seitdem ich beim Wörterbuch insgesamt 6 Minuspunkte bekam, wegen 3 Nullpointern, bin ich da etwas vorsichtig geworden. Nunja, vielleicht war es auch ein anderer Zusammenhang.


Ich wünschte, ich hätte endlich mehr kontrollierte Aufgaben, als bis Übung 5. :-/


Hallo zusammen,
Ich hätte mal ein kleines Problem, was ich gerade irgendwie nicht gebacken bekomme. Ich hatte mir das Ganze ebenfalls so überlegt, dass gleich beim einfügen in die Schlange sortiert wird und die Schlange an sich aber nicht zyklisch ist (Geschmackssache, würde ich sagen). Dazu habe ich mir jetzt einen Konstruktor für eine leere Warteschlange gemacht, wobei die Zeiger für kopf und ende über zwei spezielle Elemente realisiert werden, um die Behandlung der Liste zu vereinfachen.

hier mal ein Auszug:

public Warteschlange(){
this.kopf = new Element(kopf.wert(), kopf.prioritaet());
this.ende = new Element(kopf.wert(), kopf.prioritaet());
… //es folgen die Verknüpfungen
}

Die meisten anderen Methoden sind bereits implementiert (bis auf enqueAll, dequeue für bestimmte Werte). Jedoch bekomme ich beim testen der restlichen methoden (also beim erzeugen einer Warteschlange in der main) sofort NullPointer bei kopf und ende :wink: Was stimmt denn mit der Initialisierung der beiden nicht, oder muss ich in der Aufgabe gar das auf andere Weise lösen, ohne mir zwei Elemente extra dafür zu erstellen? Klingt vielleicht für jemanden hier trivial, oder doof :smiley: - aber irgendwie weiss ich grad auch nicht.


hm,

also sonderfall fällt mir noch dequeue(MIN_VALUE) ein (bzw. die priorität, die das header element, falls vorhanden, hat) funktioniert bei mir schonmal nicht 100%, aber da ich nich rausfinde woran das liegt, hoff ich einfach, dasses nich getestet wird :wink:

edit: d00dle, wenn du this.kopf quasi erst erschaffst, dann gibts doch noch überhaupt kein kopf.wert()?
warum machst du nicht einfach this.kopf = new Element(null,MAX_VALUE) und beim ende MIN_VALUE oder so?