Anfängerproblem mit arrays
-
Hallo an alle ich bin neu und ich soll fürs studium ein sudokulöser in c++ programmieren.
hier die quelltextevorgP4.2.h:
typedef unsigned char SD [9][9][10];
//SD[i][j][0] ist Anzahl der offenen Möglichkeiten auf Position (i,j)
//SD[i][j][k]==true genau dann wenn die Zahl k eine offene Möglichkeit istchar sudoku(SD);
vorgP4.2.c++
#include<stdio.h>
#include<stdlib.h>
#include"vorgP4.2.h"
#include<iostream.h>void lese_SD(SD sd)
{
unsigned c;
for(unsigned i=0;i<9;++i)
for(unsigned j=0;j<9;++j)
{
scanf("%u",&c);
for(unsigned k=1;k<10;++k) sd[i][j][k]=(c?0:1);
sd[i][j][0]=(c?1:9);
if(c) sd[i][j][c]=1;
}
}void drucke_SD(SD sd)
{
for(unsigned i=0;i<9;++i)
{
for(unsigned j=0;j<9;++j)
{
if(sd[i][j][0]!=1) { printf("%u ",0); continue; }
for(unsigned k=1;k<10;++k)if(sd[i][j][k]) printf("%u ",k);
}
printf("\n");
}
}SD sd;
main()
{
lese_SD(sd);
drucke_SD(sd);
printf("\n");
if(sudoku(sd)) drucke_SD(sd);
else printf("unloesbar");
system("PAUSE");}
und schließlich aufgP4.4.c++:
#include "vorgP4.2.h"
char sudoku(SD sd)
{
SD sd2;
sd2=sd <---------------hier !
// rest hab ich weggelassen
}da an der markierten stelle bekomme ich bei compilieren mit Dev-C++ 4.9.9.2
den Fehler:
In functionchar sudoku(unsigned char (*)[9][10])': incompatible types in assignment of \unsigned char (*)[9][10]' to `unsigned char[9][9][10]'und meine frage ist WIESO?????
SD ist ja vom typ char[9][9][10] was heißt das (*) ???????????????danke
-
1. Nutze die Tags: [ cpp] und [/cpp]
2. Finde ich deine Klammer-Setzung sehr komisch... (ich finde, dass '{' bzw '}' stets auf einer eigenen Zeile sein sollten - außer bei while und nem else vll - aber so finde ich, ist es sehr schwer zu lesen...Außerdem:
Müsste es nicht so heißen:typedef bool[9][9][9] SD?
"SD[i][j][k]==true genau dann wenn die Zahl k eine offene Möglichkeit"
Würde ich eben mit ner Fkt prüfen, die arr[x_fest][y_fest][9] übergeben bekommt und dann guckt, wie viele z (mein Name für die dritte Dimension) true sind - wenn das nur eins ist, dann sollte die Fkt True zurückgeben - aber für so ne Fkt seh ich eigtl keine Notwendigkeit...Wenn du es nicht mit bool machen willst, dann nimm eben
typedef unsigned __int8[9][9] SD;Aber nen Sinn für int[9][9][9] sehe ich NICHT...
Alternativ könntest du dir auch mal std::vector angucken um das ganze auch für andere Größen als nur 9x9 und für mehr, als nur 0...9 zu basteln - aber das geht sicherlich über die Aufgabe hinaus... ^^
Denk mal drüber nach - wenn du meine Idee doof findest, dann post eben noch ma das, was du schon hast aber mit cpp-Tags ^^
Byebye
//Edit's: Naja - waren so ne Edmund-Stoiber-Sätze dabei (ich wusste am Ende nicht mehr, was ich am Anfang geschrieben hatte und dementsprechend wenig Sinn hat das ganze dann gemacht ^^)

-
Ich will ja nur n 2. feld vom typ SD erstellen auf welches ich das erste speichere, sozusagen als hilfsarray. wenn ich alles im originale sd array mache weiß das programm ja ne mehr welche einträge bei backtracking schon drinstanden und welche als"versuch" dazugekommen sind
-> die vorg... datein sind vorgaben die ich nicht bearbeiten darf!
alles was ich ändern kann ist in aufgP4.2.c++
ich versteh den Fehler des compilers ne warum kann ich sd nicht in sd2 speichern obwohl sd2 vom typ SD ist und sd auch vom typ SD?????????????????????????????
-
Ganz einfach: Weil man nen Sodoku niemals mit Bruteforce (wildes durchprobieren) lösen sollte ^^ Also sagst du am Anfang, dass überall ALLE Zahlen reindürfen - und schließt nach und nach aus - so hast du überall dort 100pro die RICHTIGE Zahl drin stehen, wo es nur noch ein true in der z-dim gibt...
Wenn du es wirklich so machen musst/willst, dann nimm ma cpp tags und post noch ma, wenn du es so machen musst - und vll ma dazuerklären, warum du 3 Dimensionen mit ints brauchst... Versteh ich nämlich noch immer nicht, aber vll bin ich gerad (oder allgemein ^^) auch einfach zu doof ;o)
Ich bin dann aber erst ma inRL
bb
-
vorgP4.2.c++:
#include<stdio.h> #include<stdlib.h> #include"vorgP4.2.h" #include<iostream.h> void lese_SD(SD sd) { unsigned c; for(unsigned i=0;i<9;++i) for(unsigned j=0;j<9;++j) { scanf("%u",&c); for(unsigned k=1;k<10;++k) sd[i][j][k]=(c?0:1); sd[i][j][0]=(c?1:9); if(c) sd[i][j][c]=1; } } void drucke_SD(SD sd) { for(unsigned i=0;i<9;++i) { for(unsigned j=0;j<9;++j) { if(sd[i][j][0]!=1) { printf("%u ",0); continue; } for(unsigned k=1;k<10;++k)if(sd[i][j][k]) printf("%u ",k); } printf("\n"); } } SD sd; main() { lese_SD(sd); drucke_SD(sd); printf("\n"); if(sudoku(sd)) drucke_SD(sd); else printf("unloesbar"); system("PAUSE"); }vorgP4.2.h:
typedef unsigned char SD [9][9][10]; //SD[i][j][0] ist Anzahl der offenen Möglichkeiten auf Position (i,j) //SD[i][j][k]==true genau dann wenn die Zahl k eine offene Möglichkeit ist char sudoku(SD);und dann die die ich bearbeiten darf:
aufgP4.2.c++:#include "vorgP4.2.h" char sudoku(SD sd) { SD sd2; sd2=sd; // <----------hier ist der fehler }meine algemeine algorithmus idee:
1. tst ob sudoku voll ist (überall zahlen drin)
JA: feststellen ob diese Lösung korrekt ist
JA: rückgabe
NEIN return 0;
NEIN:
suche freien Platz
Schleife von 1 bis 9
darf ich diesezahl einsetzen?
JA: existiert eine Lösung mit dieser zahl?(neuaufruf der ganzen funktion mit zusätzlichem eintrag)
JA: dies ist Lösung
Nein return 0so die idee als backtracking lösung mit den vorgaben der profs
ich hoffe es hilft euch so das ihr mir helfen könnt
-
Gib deinem Prof ne Kugel und sag ihm dass das so unperformant wie nur geht ist, was der von euch verlangt. Ein Sodoku kann mann durch andere Verfahren wesentlich einfacher und in viel kürzerer Zeit lösen!
-
Sag ihm das aber bevor du ihm die "Kugel" gibst.
Sonst versteht er es nicht.
-
Probier es mit der Sudoku Spielverderber Lösung.
Das Lösungsprogramm sucht zunächst das erste freie Feld und probiert dann nacheinander alle Ziffern beginnend mit der Eins aus. Wenn eine Ziffer gefunden wurde, die die Spielregeln nicht verletzt, dann wird der Algorithmus mit dem nächsten freien Feld wiederholt. Wenn es kein freies Feld mehr gibt, dann ist das Rätsel gelöst. Falls jedoch keine der Ziffern 1 bis 9 in das Feld passt, dann geht das Programm ein Feld zurück und wiederholt das ganze mit der nächsten dort möglichen Ziffer.
Der Algorithmus lässt sich sehr elegant rekursiv formulieren, das heißt es gibt eine Lösungsfunktion solve(), die sich immer wieder selbst aufruft.
Vorstellbar, oder?
-
Das ist genau das was ich in meiner antwort aufgeschrieben hab und was ich die ganze zeit versuche umzusetzen
nur: dazu brauche ich ein "hilfsfeld" da ich nicht das ursprüngliche überschreiben kann (sonst kann das programm nicht trennen was eingabe ist und was versuch)
und das erklären des hilfsfeldes geht nicht
WIE ICH BEREITS GESAGT HATTE
-
OK ich habs jetzt mit ner schleife gelöst aber das prog arbeitet trotzdem nicht findet ihr den Fehler???
#include "vorgP4.2.h" char voll(SD sd1) { int rueck=1; for(unsigned i=0;i<9;++i) { for(unsigned j=0;j<9;++j) { if(sd1[i][j][0]>1) rueck = 0; } } return rueck; } int welche_zahl(SD sd2, int zeile, int spalte) { int rueck=0; for (unsigned k=0;k<10;++k) if (sd2[zeile][spalte][k]==1) rueck=k; return rueck; } char teste(SD sd3) { int rueck=1; //zeilentest: for(unsigned i=0;i<9;++i) { for(unsigned j=0;j<9;++j) { for(unsigned l=0;l<9;++l) { if ((welche_zahl(sd3,i,j)==welche_zahl(sd3,i,l))&&(j!=l)) rueck = 0; } } } //spaltentest for(unsigned j=0;j<9;++j) { for(unsigned i=0;i<9;++i) { for(unsigned l=0;l<9;++l) { if ((welche_zahl(sd3,i,j)==welche_zahl(sd3,l,j))&&(i!=l)) rueck = 0; } } } //boxtest for(unsigned i=0;i<9;++i) { for(unsigned j=0;j<9;++j) { for(unsigned k=((i/3)*3);k<(((i/3)*3)+3);++k) { for(unsigned l=((j/3)*3);l<(((j/3)*3)+3);++l) { if ((welche_zahl(sd3,i,j)==welche_zahl(sd3,k,l))&&((i!=k)||(j!=l))) rueck = 0; } } } } return rueck; } int freiezeile(SD sd4) { int rueck; for(unsigned i=0;i<9;++i) { for(unsigned j=0;j<9;++j) { if(sd4[i][j][0]>1) rueck = i; } } return rueck; } int freiespalte(SD sd5, int zeile) { int rueck; for(unsigned j=0;j<9;++j) { if(sd5[zeile][j][0]>1) rueck = j; } return rueck; } char sudoku(SD sd) { SD sdx; int wert=0; // sd auf sdx zuweisen: for(unsigned i=0;i<9;++i) { for(unsigned j=0;j<9;++j) { for(unsigned k=0;k<10;++k) sdx[i][j][k]=sd[i][j][k]; } } // sind alle einträge im sudoku drin? wenn ja dann prüfe ob diese Lösung so geht if (voll(sd)==1) { if(teste(sd)==1) { return 1; } else return 0; } else { // suche nächsten freien Platz int zeile = freiezeile(sd); int spalte = freiespalte(sd,zeile); for(unsigned zahl=0;zahl<9;++zahl) //trage zahl ein und löse dann { for(unsigned i=1;i<10;++i) { sdx[zeile][spalte][i]=0; } sdx[zeile][spalte][zahl]=1; sdx[zeile][spalte][0]=1; if (sudoku(sdx)==1) { for(unsigned i=0;i<9;++i) { for(unsigned j=0;j<9;++j) { for(unsigned k=0;k<10;++k) sd[i][j][k]=sdx[i][j][k]; } } return 1; } else return 0; } } }ist meine lösung die vorgaben sind :
#include<stdio.h> #include<stdlib.h> #include"vorgP4.2.h" #include<iostream.h> void lese_SD(SD sd) { unsigned c; for(unsigned i=0;i<9;++i) for(unsigned j=0;j<9;++j) { scanf("%u",&c); for(unsigned k=1;k<10;++k) sd[i][j][k]=(c?0:1); sd[i][j][0]=(c?1:9); if(c) sd[i][j][c]=1; } } void drucke_SD(SD sd) { for(unsigned i=0;i<9;++i) { for(unsigned j=0;j<9;++j) { if(sd[i][j][0]!=1) { printf("%u ",0); continue; } for(unsigned k=1;k<10;++k)if(sd[i][j][k]) printf("%u ",k); } printf("\n"); } } SD sd; main() { lese_SD(sd); drucke_SD(sd); printf("\n"); if(sudoku(sd)) drucke_SD(sd); else printf("unloesbar"); system("PAUSE"); }und
typedef unsigned char SD [9][9][10]; //SD[i][j][0] ist Anzahl der offenen Möglichkeiten auf Position (i,j) //SD[i][j][k]==true genau dann wenn die Zahl k eine offene Möglichkeit ist char sudoku(SD);danke