wie verschiebe ich die Zahlen in einem Array von rechts nach links,Java-Anfänger?

2 Antworten

Lege dir ein neues Array an. Wie bei der vorherigen Aufgabe überträgst du zunächst die Werte, die diesmal von 0 bis Arraylänge - n gehen in das neue Array. Dann holst du dir die übriggebliebenen Werte und sortierst sie an die ersten Stellen des neuen Arrays. Damit sie verkehrt herum eingetragen werden, kannst du eine Schleife nutzen, die rückwärts zählt, aber mit einem zweiten Index vorwärts einträgt.

Beispiel (gibt die Zahlen 0 bis 5 aus):

for (int i = 5, j = 0; i >= 0; --i, ++j) {
  System.out.println(j);
}

Sobald eine Zahl beim Verrücken hinten aus dem Array rausfliegt, musst du sie eben vorne wieder einordnen. Herauszufinden, wann eine Zahl rausfliegt, ist nicht schwierig. Du kennst ja ihre Position und die Länge des Arrays. In deinem Beispiel hast du ein Array der Länge 5, also hast du die Positionen 0 bis 4. Die letzte Zahl (5) ist an der Position 4. Die Anzahl der Verschiebungen n musst du ggf. auch direkt mit in die Bedingung einbauen. Kommt jetzt ganz drauf an, wie du es umsetzen möchtest. Hast du jetzt eine for-Schleife mit dem Zählerindex i, könnte das z.B. wie folgt aussehen:

for(...)
{
  if(array.length - n >= i)
  {
     //Code für die Stellen, welche hinten rausfliegen und vorne rein müssen
  }
}

In deinem Beispiel würde man also für die Position 3 (Wert=4) und Position 4 (Wert=5) wissen, dass die Werte rausfliegen.

Dabei muss dir klar sein, dass du nicht einfach array[0] ersetzen kannst, denn dort steht ein Wert drin, der noch verschoben werden muss. Du würdest ihn überschreiben. Also musst du irgendwie zwischenspeichern oder gleich das das gesamte Array (verschoben) kopieren. Hängt auch wieder davon ab, wie du es vorher getan hast. Du könntest z.B. folgendes machen:

Du machst erst einmal alles wie vorher. Unterschied: Die Werte, die hinten rausfliegen, speicherst du in einem anderen Array. Die Größe dafür kennst du: Das ist n. Erzeugen musst du das Array bereits vor der Schleife. In deinem Beispiel hätte es die Länge 2. In der Schleife weist du dem Array dann die Werte zu. Die 4 und 5 musst du darin also während der Schleife speichern. Nachdem du das Array verrückt hast, kannst du von vorne beginnend n Stellen mit den Werten aus dem Zwischenspeicher-Array (ich nenne es mal 'ram') füllen.

Also:

//Achtung: Hart implementierter Code
ram[0] = 4;
ram[1] = 5;

Jetzt den Algorithmus von vorher verwenden und die beiden Stellen vorne bekommen zuerst den Wert 0. In einem nächsten Schritt ersetzt du jetzt wie folgt:

//Achtung: Hart implementierter Code
array[0] = ram[0];
array[1] = ram[1];

Das solltest du natürlich dynamisch und nicht hart-codiert machen. Also musst du 0 und 1 durch eine int-Variable ersetzen, sodass dein Programm auch mit anderen Arrays arbeiten kann. Optimal wäre es, wenn du gar nicht erst die nullen einfügen musst. Für den Anfang ist das aber völlig ausreichend und so nutzt du den gleichen Code wieder. Das ist gut. Man sollte es als Programmierer verhindern, doppelten Code zu haben. Spätestens, wenn du nämlich etwas ändern möchtest, was doppelt vorhanden ist, hast du den doppelten Aufwand und es kann zu Problemen führen. Auch solltest du für diese Aufgabe mehrere Methoden verwenden und die Zuständigkeiten trennen. Das ist ebenfalls wichtig als Programmierer.

Wichtig ist auch: Es geht natürlich auch anders. Das ist nicht die Einzigste Möglichkeit und ich habe jetzt nicht großartig überlegt, sondern meine spontane Idee präsentiert.


TrustMeDude1 
Beitragsersteller
 15.11.2020, 20:03

ich schaffe es nicht das ganze in den Code umzusetzen :(

0
TechnikSpezi  16.11.2020, 01:13
@TrustMeDude1

Ich hab es dir mal geschrieben. Anmerkungen vorab:

  1. Ich hab jetzt das aufgegriffen, wie ich es in meiner Antwort gesagt habe. Es geht anders und sicherlich noch effizienter.
  2. Ich habe nicht auf die Zuständigkeit von Methoden geachtet. Vor allem habe ich hier nicht beachtet, dass du schon eine Methode hast, welche ein Array um 1 nach rechts schieben kann. Das solltest du ggf. aufteilen.
  3. Ich hab jetzt um 1 Uhr in der Nacht nicht großartig getestet. Man kann hier sicherlich noch etwas optimieren. Der Code soll für dich eine Möglichkeit bieten, einmal zu verstehen, wie man das umsetzen kann. Du solltest hier selbst am besten nochmal genau drüber schauen, alle Fälle testen und den Code wenn möglich effizienter gestalten.

Erst einmal der Code, danach folgen die Erläuterungen.

/**
 * @author TechnikSpezi
 */
public class ArrayShift {

	public static void main(String[] args)
	{
		int[] array = {1,2,3,4,5};
		int[] array2 = {1,2,3,4,5,6,7,8};
		int [] small = {1,2};
		druckeArray(rightShift(array, 2)); //Dein Beispiel
		druckeArray(rightShift(array2, 3));
		druckeArray(rightShift(small, 2));
	}
	
	/**
	 * @param anzahlVerschiebungen Entspricht Anzahl an Werten, die hinten rausfliegen
	 */
	public static int[] rightShift(int[] array, int anzahlVerschiebungen)
	{
		assert(array != null); //Sonst NullPointerException
		
		if(anzahlVerschiebungen == array.length) //Dann kommt genau das gleiche Array wieder raus
			return array;
		
		assert(anzahlVerschiebungen < array.length); //Sonst IndexOutOfBoundsException

		//Kopiere die Werte, die hinten rausgeschoben werden und 
		//speicher sie zwischen
		
		int[] ram = new int[anzahlVerschiebungen];
		for(int i=0; i < ram.length; i++)
		{
			ram[i] = array[array.length - anzahlVerschiebungen + i];
		}
		
		//Verschiebe das Array um anzahlVerschiebungen nach rechts
		//Ich mache das jetzt direkt um anzahlVerschiebungen Stellen, um Performance zu sparen
		
		for(int replacePosition = array.length - 1; replacePosition - anzahlVerschiebungen >= 0; replacePosition--)
		{
			array[replacePosition] = array[replacePosition - anzahlVerschiebungen];
		}
		
		//Die vorderen Werte ersetzen
		
		for(int i = 0; i < ram.length; i++)
		{
			array[i] = ram[i];
		}

		return array;
	}
	
	public static void druckeArray(int[] array)
	{
		for(int i=0; i < array.length; i++)
		{
			System.out.print(array[i] + "  ");
		}
		System.out.println();
	}
}

Kannst du dir hier besser anschauen und downloaden: https://pastebin.com/49c6fGvJ

Ergebnis:

4  5  1  2  3  
6  7  8  1  2  3  4  5  
1  2  

Erläuterungen:

  1. Die Asserts solltest du z.B. durch if-Bedingungen ersetzen, damit das Programm auch wirklich abbrechen kann. So wie ich es habe würde es weiterlaufen und ggf. in Exceptions enden.
  2. Ich habe hier das Array direkt um n bzw. anzahlVerschiebungen Stellen verschoben. Da du schon eine Methode hast, solltest du sie wiederverwenden und das vielleicht nicht so tun. Du solltest dein Programm also ggf. so schreiben, dass es immer nur um eine Stelle Schritt für Schritt verschoben wird. Das geht auf Lasten der Effizienz, bringt dich aber weiter beim Lernen und im Bezug auf die Trennung von Zuständigkeiten sowie dem Verhindern von doppeltem Code.
  3. Falls du Probleme hast die 2. for-Schleife zu verstehen, hier äquivalenter Code, den du vielleicht besser verstehst:
int replacePosition = array.length - 1;
for(int getPosition = array.length - 1 - anzahlVerschiebungen; getPosition >= 0; getPosition--)
{
	array[replacePosition] = array[getPosition];
	replacePosition--;
}

Und auch hier sollte klar sein: Kann man auch anders machen.

____

Ich hoffe, ich konnte dich weiter bringen :) Falls du Fragen oder Anmerkungen hast (um 1 Uhr Nachts habe ich vielleicht auch etwas vergessen), schreib gerne :)

0