magisches Quadrat

obelixpp

Mitglied
Guten Tag zusammen,
nachdem ich so langsam verzweifel hoffe ich das mir hier geholfen werden kann.
Ich habe folgende Aufgabenstellung (unten nachzulesen) und komme nicht weiter, weil ich leider keinen
Plan habe was genau toString sein soll. Ich habe schon alle Unterlagen von den Vorlesungen durchgesucht aber nichts dazu gefunden.


Aufgabenstellung Teil II
Schreiben Sie ein Programm, welches ein Feld mit drei Zeilen und drei Spalten erzeugt und ausgibt;
jede Zelle enthält eine Ziffer zwischen 1 und 9, wobei jede Ziffer nur genau einmal vorkommt.
Ein Beispiel für ein gültiges Feld wäre:
[1][4][6]
[3][9][8]
[7][2][5]
Erstellen Sie zur Bearbeitung dieser Aufgabe die folgenden Klassen:
RandomCell
Diese Klasse stellt eine Zelle dar, welche einen Wert zwischen 1 und 9 besitzt. Diese Information wird
in einer Variable vom Typ int gespeichert (Bezeichner = value). Schreiben Sie get- und set-Methoden
und Überschreiben Sie die Methode toString, die die Nummer in eckigen Klammern zurückgeben soll.
RandomGrid:
Diese Klasse stellt ein Feld dar. Das Feld ist ein zwei-dimensionales Array mit 3 Zeilen und 3 Spalten
vom Typ RandomCell (Bezeichner = array). Das Feld wird in der Methode init() erzeugt während die
Methode refresh() das Feld zufällig mit Werten füllt; jede Ziffer zwischen 1 und 9 kommt genau ein-
mal vor. Hinzu kommt eine Methode clear(), welche alle Zellen auf 0 setzt. Zudem kann das Feld mit
der Methode show() angezeigt werden und mit der Methode magic() kann überprüft werden, ob es
sich bei dem erzeugten Feld um ein so genanntes magisches Quadrat handelt. Sowohl Zeilen- und
Spaltensummen als auch die Summe der diagonalen Elemente ergeben darin 15. Hier ein Beispiel für
ein solches Quadrat:
[6][1][5]
[3][9][8]
[7][2][5]
Für die Erzeugung des Feldes empfiehlt sich die folgende Vorgehensweise: ArrayList mit den Werten
von 1 bis 9 füllen; jeden Wert einer zufälligen Position im Array zuweisen bzw. ein Objekt der Klasse
RandomCell mit diesem Wert erstellen; Vorgang ggfs. wiederholen, wenn diese Position schon mit
einem Wert belegt ist.
RandomTest:
In der main-Methode soll zunächst ein Objekt der Klasse RandomGrid erzeugt werden. Sodann soll
die refresh-Methode 100.000-mal aufgerufen werden, wobei nach jedem Aufruf mit der magic-
Methode überprüft werden soll, ob ein magisches Quadrat erstellt wurde; in diesem Fall soll eine
Ausgabe mit der show-Methode erzeugt werden.

Für die Klasse RandomCell habe ich bis jetzt folgendes geschrieben:

Java:
package Aufgabe2;

public class RandomCell 
{
	int value =(int) (Math.random()*10);
		
	public int getValue()
	{
		return value;
	}
	
	void setValue(int value)
	{
		this.value = value;
	}
}

getter und setter Methoden sind ja forhanden und auch die zahl zu berechnen war jetzt nicht wirklich die schwierigkeit nur wie gesagt habe ich keine Ahnung wie ich weitermachen soll.

EDIT:// Da ich gerade gesehen habe das das Thema verschoben worden ist, wollte ich nur noch kurz sagen das ich hier natürlich keine fertige Lösung erwarte, sondern Hilfe dabei dieses Problem mit dem toString zu verstehen wäre sehr nett.
 
Zuletzt bearbeitet:
G

Gast2

Gast
Die Hilfe:

Java API
Class Object

toString

public String toString()

Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method.

The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:

getClass().getName() + '@' + Integer.toHexString(hashCode())


Returns:
a string representation of the object.
 

obelixpp

Mitglied
Die Hilfe:

Java API
Class Object

toString

public String toString()

Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method.

The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:

getClass().getName() + '@' + Integer.toHexString(hashCode())


Returns:
a string representation of the object.

Kann ich das so verstehen das ich mit dieser Methode "toString" einfach alles mögliche "anschaulich" darstellen lassen kann?
Aber wo wäre dann der Sinn darin?
Ich könnte doch auch einfach "System.out.println" nutzen für etwas auszugeben?
Bzw. wie könnte ich mit dem toString etwas "formatiert" abspeichern?
 

obelixpp

Mitglied
noch ein Hinweis:
du könntest hier sogar 'java was ist tostring' in eine Suchmaschine eintippen und bekommst allerlei Hinweise,
etwa
Galileo Computing :: Java ist auch eine Insel (8. Auflage) – 10.2 Object ist die Mutter aller Klassen
10.2.2 Objektidentifikation mit toString()

Ich habe mir auch schon bei oracle die docs angeschaut, ich glaube mein problem ist eher das ich noch nicht wirklich weiß was ich mit dieser methode tostring anfangen kann.
jemand vllt ein konkretes beispiel?
 
S

SlaterB

Gast
genau meinen Link lesen?
dort steht für was toString() verwendet wird, es gibt Beispiele (Player) usw...
 

Marco13

Top Contributor
Jedes Objekt sollte sich durch die Methode toString() mit einer Zeichenkette identifizieren und den Inhalt der interessanten Attribute als Zeichenkette liefern. ...
Das Angenehme ist, dass toString() automatisch aufgerufen wird, wenn die Methoden print() oder println() mit einer Objektreferenz als Argument aufgerufen werden. Ähnliches gilt für den Zeichenkettenoperator + mit einer Objektreferenz als Operand.

Zugegeben: Das könnte man ... "zugänglicher" formulieren....

ann ich das so verstehen das ich mit dieser Methode "toString" einfach alles mögliche "anschaulich" darstellen lassen kann?

Es geht nicht nur um "anschaulich", sondern darum, schnell und einfach Informationen über ein Objekt ausgeben zu können. Eine Klasse "Person" könnte z.B. eigenschaften haben wie Vorname, Nachname, Alter... Und es ist eben praktisch, wenn bei
System.out.println(einePerson);
genau diese Informationen direkt ausgegeben werden, und man nicht
System.out.println("Vorname: "+einePerson.getVorname());
System.out.println("Nachname: "+einePerson.getNachname());
System.out.println("Alter: "+einePerson.getAlter());
hinschreiben muss. Und das erreicht man, indem man toString passend überschreibt. In deinem Fall geht es nur um diese Gitterzellen - man könnte da auch eine andere Methode überschreiben und explizit aufrufen, aber toString bietet sich eben an...
 

obelixpp

Mitglied
Zugegeben: Das könnte man ... "zugänglicher" formulieren....



Es geht nicht nur um "anschaulich", sondern darum, schnell und einfach Informationen über ein Objekt ausgeben zu können. Eine Klasse "Person" könnte z.B. eigenschaften haben wie Vorname, Nachname, Alter... Und es ist eben praktisch, wenn bei
System.out.println(einePerson);
genau diese Informationen direkt ausgegeben werden, und man nicht
System.out.println("Vorname: "+einePerson.getVorname());
System.out.println("Nachname: "+einePerson.getNachname());
System.out.println("Alter: "+einePerson.getAlter());
hinschreiben muss. Und das erreicht man, indem man toString passend überschreibt. In deinem Fall geht es nur um diese Gitterzellen - man könnte da auch eine andere Methode überschreiben und explizit aufrufen, aber toString bietet sich eben an...

Vielen vielen Dank für diese Beschreibung ich glaub ich habe es jetzt verstanden.
Also könnte das hier schon die Lösung für mein Problem sein?

Java:
	public String toString() 
	  { 
	    return "[" + value + "]"; 
	  }

und wenn ich diesen Wert nachher aufrufen möchte für meinen würfel zu füllen nutze ich quasi einfach

Java:
RandomCell array = new RandomCell();
array.toString();

oder habe ich da noch etwas übersehen?
 
S

SlaterB

Gast
das sieht schon brauchbar aus, wobei der toString() Aufruf für sich keinen Sinn macht, der Rückgabewert, der erzeugte String wird nicht genutzt,
für eine einzelne Zelle ist 'array' auch ein grausiger Variablenname
 

obelixpp

Mitglied
Also ich habe es jetzt mal so umgeschrieben:

Java:
public class RandomGrid 
{
	RandomCell array[][] = new RandomCell[3][3];
	
	public static void main(String[] args)
	{
		
	}
	
	void init()
	{
		for (int waag=0; waag < array.length; waag++)
		{
			for (int senk=0; senk < array[waag].length; senk++)
			{
				array[waag][senk] = value;	// Wert einsetzen mit dem das array an dieser Stelle gefüllt werden soll.
				System.out.print(array[waag][senk]+"\t");
			}
			System.out.println();
		}
	}
}

Momentan hänge ich an diesem Aufgabenteil,

Diese Klasse stellt ein Feld dar. Das Feld ist ein zwei-dimensionales Array mit 3 Zeilen und 3 Spalten
vom Typ RandomCell (Bezeichner = array).

zu allererst verstehe ich nicht wirklich wie ein Array vom Typ RandomCell sein kann, also kann ich quasi diesen Typ RandomCell den ich ja selbst quasi erstellt habe gleichsetzen mit anderen Datentypen wie int,String etc.?

und jetzt wollte ich das Array mit den Werten aus der anderen Klasse RandomCell füllen, die Variable dafür hatte ich value genannt allerdings weiß ich nicht wie ich jetzt aus der Klasse RandomGrid auf diesen Wert in der Klasse RandomCell zugreifen kann.
 
S

SlaterB

Gast
> also kann ich quasi diesen Typ RandomCell den ich ja selbst quasi erstellt habe gleichsetzen mit anderen Datentypen wie int,String etc.?
ja

> das Array mit den Werten aus der anderen Klasse RandomCell füllen
+
> wie ich jetzt aus der Klasse RandomGrid auf diesen Wert in der Klasse RandomCell zugreifen kann

da hast du eine falsche Sichtweise, du würdest ein int-Array auch nicht mit 'Werten aus der anderen Klasse' int befüllen,
mal abgesehen davon dass int keine richtige Klasse ist,

es gibt keine bestimmen Werte aus der anderen Klasse, schon gar nicht nur einen 'diesen Wert',
sondern es es gibt die Klasse RandomCell und jeder kann beliebig RandomCell-Objekt erstellen so wie ints und Strings,

in deiner Doppelschleife kannst du der aktuellen Array-Position ein neu erstelltest RandomCell-Objekt zuweisen,
schon hast du am Ende 9 Stück,
nicht 9 bestimmte, einfach nur 9 neue

wie man Objekte einer Klasse erzeugt ist ein Grundlagenthema
 

obelixpp

Mitglied
> also kann ich quasi diesen Typ RandomCell den ich ja selbst quasi erstellt habe gleichsetzen mit anderen Datentypen wie int,String etc.?
ja

> das Array mit den Werten aus der anderen Klasse RandomCell füllen
+
> wie ich jetzt aus der Klasse RandomGrid auf diesen Wert in der Klasse RandomCell zugreifen kann

da hast du eine falsche Sichtweise, du würdest ein int-Array auch nicht mit 'Werten aus der anderen Klasse' int befüllen,
mal abgesehen davon dass int keine richtige Klasse ist,

es gibt keine bestimmen Werte aus der anderen Klasse, schon gar nicht nur einen 'diesen Wert',
sondern es es gibt die Klasse RandomCell und jeder kann beliebig RandomCell-Objekt erstellen so wie ints und Strings,

in deiner Doppelschleife kannst du der aktuellen Array-Position ein neu erstelltest RandomCell-Objekt zuweisen,
schon hast du am Ende 9 Stück,
nicht 9 bestimmte, einfach nur 9 neue

wie man Objekte einer Klasse erzeugt ist ein Grundlagenthema

Achso, das mit der falschen Sichtweise habe ich glaube ich verstanden.
Ich darf die Klassen beispielsweise nicht so wie mehrere Excel Tabellenblätter sehen wo ich verschiedene Werte hin und her "verlinken" kann.
Sondern ich kann nur ein neues Objekt der Klasse RandomCell die ich ja erstellt habe, erstellen und dieses neue Objekt bekommt dann quasi den "Wert" den ich in der Klasse RandomCell definiert habe also in meinem Falle wird für dieses Objekt immer irgendeine Zahl zwischen 1-9 gewählt?

Ich habe es mal so umgeschrieben:

Java:
public class RandomGrid 
{
	RandomCell array[][] = new RandomCell[3][3];	
	RandomCell fill = new RandomCell();
	
	public static void main(String[] args)
	{
		init();
	}
	
	void init()
	{
		for (int waag=0; waag < array.length; waag++)
		{
			for (int senk=0; senk < array[waag].length; senk++)
			{
				array[waag][senk] = fill;	// Wert einsetzen mit dem das array an dieser Stelle gefüllt werden soll.
				System.out.print(array[waag][senk]+"\t");
			}
			System.out.println();
		}
	}
}

Allerdings bekomme ich jetzt immer die Meldung: Cannot make a static reference to a non static method
 
S

SlaterB

Gast
von der statischen main aus kannst du eben keine nichtstatische Methode aufrufen, erstelle ein RandomGrid-Objekt
und rufe dort vom Konstruktor aus init() auf oder stecke den Code in den Konstruktor,

und im Moment hast du nur ein cell-Objekt, welches du an alle Array-Positionen schreibst,
dann würde sich eine Wertänderung überall auswirken, denn alles ist ja dieselbe Zelle,
erstelle lieber 9 unterschiedliche Zellen, eben genau in Schleife, keine Variablen zu RandomCell außerhalb (vorerst)

> das mit der falschen Sichtweise habe ich glaube ich verstanden.
klingt ansonsten ganz gut, ja
 

timbeau

Gesperrter Benutzer
static void ....

Jein,

du hast deine Klasse RandomGrid, in dieser erstellst du EIN Objekt der Klasse RandomCells. Und dieses füllst du mit festen Werten in deiner init-Methode.

Du könntest diese init-Methode auch in die RandomCells-Klasse auslagern. Grundsätzlich ist jedes Zelle per Definition von int immer 0.
 

obelixpp

Mitglied
static void ....

Jein,

du hast deine Klasse RandomGrid, in dieser erstellst du EIN Objekt der Klasse RandomCells. Und dieses füllst du mit festen Werten in deiner init-Methode.

Du könntest diese init-Methode auch in die RandomCells-Klasse auslagern. Grundsätzlich ist jedes Zelle per Definition von int immer 0.

Leider ist mir per Aufgabenstellung vorgegeben wo ich welche Methoden habe, ich werde mich heute Abend wohl nochmal intensiv damit auseinandersetzen müssen.

Zu dem erstellen eines Objektes der Klasse RandomGrid, kann ich in der Klasse RandomGrid ein Objekt dieser Klasse gleichzeitig aufrufen oder wie kann ich mir das vorstellen?
Dieses ganze mit den Objekten und Klassen fällt mir noch sehr schwer.
 

obelixpp

Mitglied
Vielleicht kann sich das mal jemand angucken, ich komm einfach nicht weiter er meckert immer er könne nicht von int to RandomCell konvertieren.
ich bin echt am verzweifeln.

Java:
package Aufgabe2;

public class RandomGrid 
{
	RandomCell array[][];
	RandomCell value;
		
	public static void main(String[] args)
	{
		
	}
	
	void init()
	{
		array = new RandomCell[3][3];
	}
	
	void refresh()
	{
		value = new RandomCell();
		
		for (int waag=0; waag < array.length; waag++)
		{
			for (int senk=0; senk < array[waag].length; senk++)
			{
				array[waag][senk]=value.getValue();
			}
			System.out.println();
		}
	}
	
	
	void clear()
	{
		for (int waag=0; waag < array.length; waag++)
		{
			for (int senk=0; senk < array[waag].length; senk++)
			{
				array[waag][senk]=0;
				System.out.println(array[1][1]);
			}
			System.out.println();
		}
	}
	
	void show()
	{
		for (int waag=0; waag < array.length; waag++)
		{
			for (int senk=0; senk < array[waag].length; senk++)
			{
				array[waag][senk] = 0;
				System.out.print(array[waag][senk]+"\t");
			}
			System.out.println();
		}
	}
}
 
S

SlaterB

Gast
was ist array? wenn es ein Array von RandomCell-Objekten ist, dann haben da doch int-Werte nichts zu suchen,
denn int ist ja kein RandomCell-Objekt?!

für diesen absoluten Grundsatz war nun externe Hilfe nötig?
dann noch ein Tipp: bevor du mit Arrays hantierst, übe an einfachen Variablen:
Java:
int k = 4;
int j = new RandomCell();
RandomCell x = 4;
RandomCell y = new RandomCell();
zwei dieser Zeilen sind richtig, zwei sind falsch,
tja, auch wenn es bisschen hämisch klingt, auf dem Niveau bist du jetzt angelangt mit der letzten Frage,

welche Variablen hast du im Programm, welche Werte, was macht jede Code-Zeile im einzelnen,
solche Grundfragen doch besser genauer überlegen bevor du aufgibst und deine Aufgaben an andere weiterreichst

> er könne nicht von int to RandomCell konvertieren
besonders wenn dich der Kompiler so direkt hinweist, das sagt der doch nicht zum Spaß,
mal Nachdenken was das bedeuten könnte
 

obelixpp

Mitglied
int j = new RandomCell();
RandomCell x = 4;


Das Array "array" soll vom Typ RandomCell sein, und wird in der Methode "init()" erzeugt.
Und in "RandomCell" sollen Zufallszahlen zwischen 1-9 gespeichert werden wo jede nur einmal vorkommen darf, und diese Zahlen sollen in einer Variable "value" vom Typ int gespeichert werden.
Jetzt weiß ich allerdings nicht wie ich diese Werte die ja in einer int Variable gespeichert sind in ein Array vom Typ RandomCell bekommen soll.
 
Zuletzt bearbeitet von einem Moderator:
S

SlaterB

Gast
hör komplett auf über Zahlen und Werte und Zufall nachzudenken,
es ist vorerst vollkommen egal was RandomCell für eine Klasse ist, was darin passiert, die Klasse kann auch vereinfacht erstmal als
Java:
public class RandomCell {

}
definiert werden,

in eine RandomCell-Variable kann nur ein RandomCell-Objekt rein,
im Array ist es absolut dasselbe, es kommen RandomCell-Objekte hinein,
nichts weiter ist dazu zu sagen,
überlege und ziehe Schlüsse
 

Pommes9485

Bekanntes Mitglied
Dir muss klar sein, das int(also Zahlen) nur nichts, also wirklich überhaupt nichts mit deiner eigenen Klasse zutun haben. Du kannst sie weder vergleichen noch einander zuweisen. Du kannst ja auch nicht ein Auto mit einem Baum vergleichen oder sogar das Auto den Wert des Baum zuweisen.

Eine Array ist nur eine Aneinanderreihung von Werten der jeweiligen Klasse. Das heißt du kannst der Array:
Java:
int[] u = new int[49]
kein Wort zuwesien und auch mit der eigenen Klasse ist es nicht möglich. Stell dir die Array vor, als Ketten die die Autos zusammenhalten. Trotzdem kannst du nicht die Autos mit dem Baum vergleichen.
 

obelixpp

Mitglied
von der statischen main aus kannst du eben keine nichtstatische Methode aufrufen, erstelle ein RandomGrid-Objekt
und rufe dort vom Konstruktor aus init() auf oder stecke den Code in den Konstruktor,

und im Moment hast du nur ein cell-Objekt, welches du an alle Array-Positionen schreibst,
dann würde sich eine Wertänderung überall auswirken, denn alles ist ja dieselbe Zelle,
erstelle lieber 9 unterschiedliche Zellen, eben genau in Schleife, keine Variablen zu RandomCell außerhalb (vorerst)

> das mit der falschen Sichtweise habe ich glaube ich verstanden.
klingt ansonsten ganz gut, ja

Ich hab das Programm jetzt soweit fast fertig, nur steh ich im Moment total aufem Schlauch, und zwar bin ich zu blöd 9 verschiedene Cell Objekte in einer for Schleife erstellen zu lassen..

Java:
// schreibt neue Zufallszahlen in alle Zellen des Arrays
	void refresh()
	{
		value = new RandomCell(0);
		value.getValue();
		
		RandomCell wert[] = new RandomCell[9];
		
		for(int a=0; a < wert.length; a++)
		{
			wert[a] = value;
			//System.out.println("Wert: "+value);
		}

		for(int i=0; i < array.length; i++)
		{
			for(int j=0;j<array[i].length;j++)
			{
				array[i][j] = value;
			}
		}
		
	}
 
S

SlaterB

Gast
tja,
[c]= value;[/c]
ist in beiden Schleifen schlecht,
dir ist die Formulierung
[c]= neues Cell-Objekt[/c] wirklich nicht bekannt?

obwohl du an anderer Stelle, für die Variablen value, problemlos
[c]= neues Cell-Objekt[/c]
stehen hast, in vorherigen geposteten Code schon gesehen (edit: in diesen aktuellen Code auch..)?

was macht für dich den Unterschied aus, einer Variablen ein neues Objekt zuzuweisen oder einer Array-Position?
da gibt es keinen Unterschied
 

obelixpp

Mitglied
tja,
[c]= value;[/c]
ist in beiden Schleifen schlecht,
dir ist die Formulierung
[c]= neues Cell-Objekt[/c] wirklich nicht bekannt?

obwohl du an anderer Stelle, für die Variablen value, problemlos
[c]= neues Cell-Objekt[/c]
stehen hast, in vorherigen geposteten Code schon gesehen (edit: in diesen aktuellen Code auch..)?

Danke, für diesen Hinweis :toll:

Ich glaube ich denk die meiste Zeit einfach zu kompliziert.
 

obelixpp

Mitglied
Ich wollte überprüfen ob in dem array zweimal dieselbe Zahl vorkommt aber irgendwie will es nicht so wie ich will,
jemand eine Idee wie ich daran gehen könnte?
 

obelixpp

Mitglied
Ich habe jetzt soweit meine Lösungsidee geschrieben aber es funktioniert nicht, hat vielleicht jemand eine Idee woran das liegt?

Java:
boolean wert = false;
		while(wert == false)
		{
		
			for(int i=0; i < array.length; i++)
			{
				for(int j=0;j<array[i].length;j++)
				{	
					array[i][j] = new RandomCell(0);
				}
			}
		
			for(int k=0; k < array.length; k++)
			{
				for(int l=0;l < array[k].length; l++)
				{
					if(array[k] == array[l])
					{
						wert = false;
					}
					else
						wert = true;
				}
			}
		}
 
F

Firephoenix

Gast
Du hast eine 2-Dimensionale Datenstruktur, auf der Willst du eine Operation für jedes Element durchführen.

In den Oberen Zeilen findest du dafür ein Beispiel, hier ist die Operation: neues Element erzeugen.

Jetzt ändert sich deine Operation.
Du prüfst für jedes Element ob es nochmal in der Datenstruktur vorkommt.

Wie prüfst du ob ein Element in der Datenstruktur doppelt vorkommt?
Du gehst einmal über die komplette Datenstruktur und prüfst alle Elemente außer dem aktuellem.

Die Operation oben ersetzt du also strikt mit der Methode der suche, überlegst dir wann beim suchen der Fall eintritt, dass du beim aktuellem Element bist und fertig :)

Gruß
 

Neue Themen


Oben