neuling96 |
Array TEst
Beim Spiel Sudoku muss ein Gitter nach bestimmten Regeln mit Ziffern gefüllt werden.
Der Parameter
int[] zeile der untenstehenden Methode
gueltigeZeile
ist ein Array der Länge 9, wobei
jedes Element eine Ziffer zwischen 1 und 9 (jeweils unterschiedlich) ist. Implementieren Sie diese Methode so, dass sie
true zurückgibt, genau dann wenn jede dieser Ziffe
rn genau einmal in zeile vor
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
|
class Sudoku {
public static boolean gueltigeZeile(int[] zeile) {
loop1:
for (i=0,i<9,i++){
boolean A= true;
for(y=0,y<9,y++){
If(!(i==y) {
If( zeile[i]==zeile[y])
boolean A= false;
break loop1
}
}
} |
|
|
Karlito |
Hallo neuling96,
- Du machst unnötig viele Vergleiche. Angenommen i ist 1 (das zweite Element), dann musst Du doch nicht noch mal prüfen, ob es sich von y=0 unterscheided... Wenn Du den Start der zweiten schleife geschickt wählst, brauchst du auch nicht prüfen, ob i!=y.
- A müsste den richtigen Wert haben. Es ist jedoch so, dass Du A auch noch zurückgeben musst...
Gruß,
Karlito |
neuling96 |
RE: Array TEst
hallo,
ich verusche deine Vorschläge umzusetzen:
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
|
class Sudoku {
public static boolean gueltigeZeile(int[] zeile) {
loop1:
for (i=0,i<9,i++){
boolean A= true;
for(y=9;y>0,y--){
If( zeile[i]==zeile[y])
boolean A= false;
break loop1
}
}
If boolean A= true{
return gueltige Zeile;
}else{
return ungueltige Zeile;
}
} |
|
|
Karlito |
Hallöchen,
mal ein paar Tipps:
Fange erstmal gaaaanz einfach an. Das mache ich auch so, wenn ich eine neue Programmierspache lerne. D.h. entwickle dein Programm Schritt für Schritt und schaue bei jedem Schritt, dass dein Programm macht was du willst. Sehr wichtig dabei: lerne wie ein Debugger funktioniert um dein Programm bei jedem Schritt zu beobachten. Wenn Du keinen Debugger benutzen kannst oder zusätzlich dazu kannst du Ausgaben Programmieren. Der erste Schritt wäre also erst einmal ein lauffähiges Programm. Beispiel dein Sudoku-Programm:
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
|
public class Sudoku {
public static void main(String[] args) {
int[] beispiel1 = {1,1,2,3}; //falsche länge
int[] beispiel2 = {1,1,2,3,5,6,8,1,2}; //doppelte...
int[] beispiel3 = {1,2,3,4,5,6,7,8,9}; //gültig
System.out.println(gueltigeZeile(beispiel1));
System.out.println(gueltigeZeile(beispiel2));
System.out.println(gueltigeZeile(beispiel3));
}
static boolean gueltigeZeile(int[] zeile)
{
boolean erg = false; //Ergebnisvariable
return erg;
}
}
|
|
Danach kannst Du das Programm weiter entwickeln und bei jedem Schritt testen, ob es das Richtige macht.
Bsp:
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
|
public class Sudoku {
public static void main(String[] args) {
int[] beispiel1 = {1,1,2,3}; //falsche länge
int[] beispiel2 = {1,1,2,3,5,6,8,1,2}; //doppelte...
int[] beispiel3 = {1,2,3,4,5,6,7,8,9}; //gültig
System.out.println(gueltigeZeile(beispiel1)); // führt zu fehler, weil zu kurz
System.out.println(gueltigeZeile(beispiel2));
System.out.println(gueltigeZeile(beispiel3));
}
static boolean gueltigeZeile(int[] zeile)
{
boolean erg = true; //Ergebnisvariable
loop1: for(int i=0; i<9; i++)
{
for(int y=0; y<9; y++)
{
if(i==y)
{
continue;
}
else
{
if(zeile[i]==zeile[y])
{
erg = false;
}
}
}
}
return erg;
}
}
|
|
Die Fehlerfreie Variante (hoffe ich zumindest
)
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
|
public class Sudoku {
public static void main(String[] args) {
int[] beispiel1 = {1,1,2,3}; //falsche länge
int[] beispiel2 = {1,1,2,3,5,6,8,1,2}; //doppelte...
int[] beispiel3 = {1,2,3,4,5,6,7,8,9}; //gültig
System.out.println(gueltigeZeile(beispiel1)); // führt zu fehler, weil zu kurz
System.out.println(gueltigeZeile(beispiel2));
System.out.println(gueltigeZeile(beispiel3));
}
static boolean gueltigeZeile(int[] zeile)
{
boolean erg = true; //Ergebnisvariable
if(zeile.length != 9)
{
erg = false;
}
loop1: for(int i=0; erg==true&&i<9; i++)
{
for(int y=0; y<9; y++)
{
if(i==y)
{
continue;
}
else
{
if(zeile[i]==zeile[y])
{
erg = false;
}
}
}
}
return erg;
}
}
|
|
Und dann die Optimierung (keine doppelten Vergleiche)
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
|
public class Sudoku {
public static void main(String[] args) {
int[] beispiel1 = {1,1,2,3}; //falsche länge
int[] beispiel2 = {1,1,2,3,5,6,8,1,2}; //doppelte...
int[] beispiel3 = {1,2,3,4,5,6,7,8,9}; //gültig
System.out.println(gueltigeZeile(beispiel1)); // führt zu fehler, weil zu kurz
System.out.println(gueltigeZeile(beispiel2));
System.out.println(gueltigeZeile(beispiel3));
}
static boolean gueltigeZeile(int[] zeile)
{
boolean erg = true; //Ergebnisvariable
if(zeile.length != 9)
{
erg = false;
}
loop1: for(int i=0; erg==true&&i<9; i++) //erg&&i<9 würde hier eigentlich reichen...
{
for(int y=i+1; y<9; y++)
{
if(i==y)
{
continue;
}
else
{
if(zeile[i]==zeile[y])
{
erg = false;
break loop1;
}
}
}
}
return erg;
}
}
|
|
Übrigens: je mehr Testfälle, desto besser und am Besten Du machst dir vorher Gedanken, in welchen Fällen dein Algorithmus fehlschlagen könnte.
Gruß,
Karlito |
neuling96 |
Vielen Dank für deinen tollen Beitrag
Beim diesem Code spukt der Compiler keinen Fehler aus
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
|
class Sudoku {
public static boolean gueltigeZeile(int[] zeile) {
boolean A= true;
loop1: for (int i=0;i<9;i++)
{
for(int y=9;y>0;y--)
{
if( zeile[i]==zeile[y])
{
A= false;
break loop1;
}
}
} if (A == true)
{
return A;
} else {
return false;
}
}
} |
|
allerdings wenn ich den code erweitere
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
|
class Sudoku {
public static boolean gueltigeZeile(int[] zeile) {
boolean A= true;
loop1: for (int i=0;i<9;i++)
{
for(int y=9;y>0;y--)
{
if( zeile[i]==zeile[y])
{
A= false;
break loop1;
}
}
} if (A == true)
{
return A;
} else {
return false;
}
}
}
public static void main(String[] args) {
int[] beispiel1 = {1,1,2,3}; //falsche länge
int[] beispiel2 = {1,1,2,3,5,6,8,1,2}; //doppelte...
int[] beispiel3 = {1,2,3,4,5,6,7,8,9}; //gültig
System.out.println(gueltigeZeile(beispiel1)); // führt zu fehler, weil zu kurz
System.out.println(gueltigeZeile(beispiel2));
System.out.println(gueltigeZeile(beispiel3));
} |
|
funktionert gar nichts!
Was mache ich falsch? |
eulerscheZahl |
- Die main ist außerhalb der Klasse
- Du hast den Schutz entfernt, dass bei einer Länge != 9 die Schleife nicht betreten wird
- Arrays fangen in Java bei Index 0 an, mit y = 9 als Schleifenanfang hast du schon verloren
- Du prüfst, ob zeile[3]==zeile[3] (für die 3 beliebige andere Zahl einsetzen). Karlito musste das nicht tun, weil er das schon durch die Schleifenzähler verhindert hat. In diesem Schritt wird immer ein false zurückgegeben
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
|
if (A == true)
{
return A;
}
else
{
return false;
}
|
|
hier tut es auch ein return A;. Das ist kürzer und leichter verständlich.
Und noch eine andere Möglichkeit, an das Problem heranzugehen:
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
|
public static boolean gueltigeZeile(int[] zeile)
{
if (zeile.length != 9) return false;
boolean[] found = new boolean[zeile.length];
for (int i = 0; i < zeile.length; i++) {
if (zeile[i] < 1 || zeile[i] > zeile.length || found[zeile[i] - 1]) {
return false;
}
found[zeile[i] - 1] = true;
}
return true;
} |
|
Es wird in einem zweiten Array gespeichert, ob eine Zahl schon vorkam.
Vorteil: jede Zahl des zu prüfenden Array muss nur einmal gelesen werden (bei deinem Code wächst die Zahl der Vergleiche quadratisch zur Länge)
Nachteil: es wird zusätzlicher Speicher benötigt, um sich zu merken, welche Zahlen schon gefunden wurden. |