Java Variablen Vertauschen?

5 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

Stell dir vor, du hast zwei Gläser vor dir stehen. Ein Glas ist mit blauer Flüssigkeit gefüllt und das andere mit roter Flüssigkeit.

glas1 = "blau"
glas2 = "rot"

Nun soll der Inhalt beider Gefässe miteinander vertauscht werden.

An der Stelle dürfte klar sein, dass eines der beiden Gläser seinen Inhalt erst irgendwo zwischenlagern muss. Ein drittes Glas wird eingesetzt und mit dem Inhalt eines der beiden Gläser (egal welches) gefüllt.

glas3 = glas1

Das heißt auch, der Inhalt von glas1 kann nun gefahrlos überschrieben werden. Das dritte Glas hält den Wert ja nun.

Also geben wir den Inhalt vom zweiten Glas an das erste Glas weiter.

glas1 = glas2

Und im letzten Schritt bekommt das zweite Glas den Inhalt vom dritten Glas:

glas2 = glas3

Zum Abschluss zeige ich es noch einmal an einem konkreten Beispiel mit Java. Ich wähle hierbei Variablen mit numerischen Werten.

int first = 1;
int second = 2;

int temp = first;
first = second;
second = temp;

Oder bei einem Array:

int[] numbers = new int[] { 1, 2 };

int temp = numbers[0];
numbers[0] = numbers[1];
numbers[1] = temp;

Antwort von @MarekJulien, mit Erklärung:

// Ausgangslage
int a = 1;
int b = 2;

// Vertauschen:
int c = a; // wir benötigen die Variable c, um einen der Werte, entweder a oder b zu erhalten, andernfalls würden wir den Wert nicht mehr haben
int a = b; // nun weißen wir der Variable a den Wert von b zu
int b = c; // Da jetzt a den Wert von b hat, wissen wir ihn eigentlich nicht. Deshalb haben wir c als temporäre "Halter"-Variable deklariert. Wir weisen b dem Wert von c zu, welcher der selbe vom "alten" a ist.

hier eine Variante ohne einer temporären Variable

diese Methode funktioniert mit XOR

a = 9;

b = 10;

a = a ^ b; //a = 3 | b = 10

b = a ^ b; // a = 3 | b = 9

a = a ^ b; // a = 10 | b = 9


PeterLustig1999  26.02.2021, 00:11

Die Frage ist: Ist diese Variante schneller?

Die schnellste Variante, die ich kenne, ist in C++, mit Move-Semantik. Mich interessiert einfach nur, wie performant diese Lösung im Vergleich ist.

0
Mike0x07C9  26.02.2021, 00:26
@PeterLustig1999

Move-Semantik kannst du nur bei einem Move Constructor verwenden.

Und beim der Move-Semantik ist es eher eine Zuweisung als eine Vertauschung von Variablen

Korrigiere mich wenn ich bezüglich der Move-Semantik falsch liege

Wenn du auf der Suche bist performant Objekt zu vertauschen empfehle ich bei komplexen Strukturen und Klassen nur mit deren Speicheradressen zu arbeiten:

  1. Speichere in einen integer(bei 32Bit Architektur) oder in einem long(bei 64Bit Architektur) die Speicher-Adressen von den Objekten die du vertauschen möchtest.
  2. vertausch nun die integer mit der XOR Variante
  3. caste die integer zurück in die ursprünglichen Objekt-Typen

Dieser Vorgang ist gerade dann Vorteilhaft wenn du mit Strukturen oder auch Klassen arbeitest die sehr viel Speicher allokieren müssen bei der Initialisierung

Ich habe diese Methode ausprobiert mit Klassen die 100 Bytes groß waren da ich sehr häufig im Programm diese sortieren musste, war diese Methode optimal.

Da hier nicht jede einzelne Field Variable getauscht wird sondern auf einmal das komplette Objekt.

0
PeterLustig1999  26.02.2021, 00:57
@Mike0x07C9

Das ist natürlich korrekt. Für ints ist das Blödsinn. Es geht mir aber tatsächlich um um Objekte, die einen solchen Konstruktur haben, schließlich müssen die ja meistens ausgetauscht werden, wenn man beispielsweise einen Container sortiert - je nachdem, wie dieser aufgebaut ist. Bei einer LinkedList kann man natürlich einfach die Link-Objekte austauschen, bei einem Array wird das ein bisschen schwieriger, wenn man die Objekte abspeichert, statt Referenzen auf sie.

Ähm... Ich denke, so funktioniert das nicht wirklich, wenn es darum geht, die Daten hinter zwei Variablen auszutauschen. Natürlich ist das mit Pointern ein wenig leichter, das ist korrekt.

Das Problem mit Pointern ist, dass sie schnelle Iteration erschweren. Schließlich wird beispielsweise bei einem Zugriff auf ein Array nicht nur das Element, sondern auch eine ganze Reihe Daten vor und hinter dem Element im RAM in den Cache geladen. Wenn die Objekte überall im Speicher verteilt sind und man nur die Pointer für den Zugriff hat, ist eine effiziente Nutzung des Prozessor-Caches nicht möglich. Und gerade in diesen Fällen kommt man um eine Swap-Implementierung mittels Move-Semantik nicht drum herum.

Dass das mit Move-Konstruktoren bei ints aber nicht funktioniert, ist klar. Ich hatte hier mal wieder nen ziemlichen Brain-Fart, entschuldige.

1

a = 1

b = 2

c = a

a = b

b = c

Woher ich das weiß:Hobby – Intensives Hobby Comuter & Technik seit etwa 10 Jahren

MarekJulien  25.02.2021, 23:59

Ist es das oder habe ich die Frage falsch verstanden?

0
erentard 
Fragesteller
 26.02.2021, 00:06
@MarekJulien

Nein hast du schon richtig Verstanden aber ich bräuchte eine Erklärung

0
MarekJulien  26.02.2021, 00:07
@erentard

Wie der Zuweisungs-Operator funktioniert weist du sicherlich, spiele das Ganze doch einmal in seinem Kopf durch, denke wie der Computer.

0
PeterLustig1999  26.02.2021, 00:00

Die vorletzte Zeile hast du falsch herum. Eigentlich müsste es hier a = b heißen.

Andere Frage. Warum nennst du ihm hier die Lösung, statt ihm Denkanstöße zu geben, wie er selbst auf die Lösung kommt? So lernt der Fragesteller nur, sich Dinge aus dem Netz zu suchen, die er nicht versteht. Programmieren lernt man so eher nicht.

1
MarekJulien  26.02.2021, 00:04
@PeterLustig1999

Danke für den Hinweis, wurde korrigiert. Ich bin der Meinung dass man die Sachen lernt wenn man sie lernen möchte, also wenn er das nur für eine Informatikhausaufgabe braucht, es ihn aber eigentlich nicht interessiert hat er direkt die Lösung. Wenn er es lernen möchte ist es seine Entscheidung ob er einfach nur kopiert oder das ganze verstehen möchte.

Ich gebe dir Recht, dass man durch eigenes denken schneller lernt, aber Aufgaben in diesem Bereich findet man nahezu unbegrenzt...

0
PeterLustig1999  26.02.2021, 00:08
@MarekJulien

Nun, der Fragesteller hat zumindest meinen Kommentar als hilfreich markiert. Weiß ich nicht, wie ich das werten soll.

Aber selbst, wenn's sich tatsächlich nur um eine Hausaufgabe handeln sollte: Gelernt hat der Fragesteller dadurch nun nichts mehr. Und darum geht es bei Hausaufgaben ja eigentlich. Darum, etwas zu lernen, etwas zu verstehen.

Ich meine, ich habe Kommillitonen, die genau so Mathematik gelernt haben und nun Informatik studieren. Die sind dann im fünften Semester und verkacken immer noch Analysis 1, weil sie nie gelernt haben, wie Bruchrechnung funktioniert, sondern immer nur den Taschenrechner bemüht haben. Damit tut man den Menschen keinen Gefallen.

0
MarekJulien  26.02.2021, 00:12
@PeterLustig1999

Dann leben wir nach anderen Denkweisen. Ich bin der Meinung er wird alles perfekt verstehen wenn dass will, wenn nicht eben nicht. Ich als Gutefrage-Fragenbeantworter sollte nicht entscheiden, ob er das Ganze verteht oder nicht, dass macht er.

0
MarekJulien  26.02.2021, 00:14
@PeterLustig1999

Ich lerne Dinge sehr gut wenn ich die Lösung zu Problemen sehe, wenn ich sie selbst erarbeite natürlich besser, aber wie ich schon schrieb kann er sich mit so vielen Problemen beschäftigen wie er möchte

0
Akamye  26.02.2021, 00:07

das sieht doch sauber aus, eine präzise Erklärung für das ganze wäre aber auch angebracht

2
MarekJulien  26.02.2021, 00:08
@Akamye

Dafür muss man nur wissen, wie Vaiablen und der Zuweisungsoperator funktionieren, und da findet man im Netz sicherlich genügend Erklärungen für.

0

nun den. denk wie der computer. wie würde der computer handeln?