Monkey7 Δημοσ. 30 Απριλίου 2011 Μέλος Δημοσ. 30 Απριλίου 2011 ευχαριστώ πολύ για τις συμβουλές σου έκανα κάποιες τροποποιήσεις. Στη συνάρτηση που ανόιγει τα κουτιά έχω ένα θέμα.την έχω φτιάξει ώστε να ανοίγει ένα κουτί και να βρίσκει άμα υπάρχει νάρκη γύρο και αναλόγος να πράτει.Το πρόβλημα μου είναι ότι δεν μπορώ να βρω πως με αναδρομή θα την κάνω να ανοίγει και τα άλλα κουτια κενά κουτιά > void anoigma(int a, int b, int n, int m, int **pa) { int i,j,k=0,narkes=0; if(a==0)//ama einai sta panw oria { for(i=a;i<a+2;i++) { if(b==0)//ama einai sta aristera { for(j=b;j<b+2;j++) { if(pa[i][j]==1) { narkes=narkes+1; } } } else if(b==m)//ama einai sta deksia { for(j=b-1;j<b+1;j++) { if(pa[i][j]==1) { narkes=narkes+1; } } } else { for(j=b-1;j<b+2;j++) { if(pa[i][j]==1) { narkes=narkes+1; } } } } } else if(a==n-1)//ama einai sta katw oria { for(i=a-1;i<a+1;i++) { if(b==0)//ama einai sta aristera { for(j=b;j<b+2;j++) { if(pa[i][j]==1) { narkes=narkes+1; } } } else if(b==m)//ama einai sta deksia { for(j=b-1;j<b+1;j++) { if(pa[i][j]==1) { narkes=narkes+1; } } } else { for(j=b-1;j<b+2;j++) { if(pa[i][j]==1) { narkes=narkes+1; } } } } } else//opoudipote allou ektos apo oria { for(i=a-1;i<a+2;i++) { for(j=b-1;j<b+2;j++) { if(pa[i][j]==1) { narkes=narkes+1; } } } } if(narkes==0) { pa[a][b]=9; } else { pa[a][b]=narkes; } k=k+1; } Μη δώσετε σημασία στο k.(το έχω να μετράει τα κουτιά που έχουν ανοίξει αλλά δεν το έχω φτιάξει ακόμα)
Monkey7 Δημοσ. 30 Απριλίου 2011 Μέλος Δημοσ. 30 Απριλίου 2011 Μετά απο πολύ ψάξιμο έφτιαξα μία συνάρτηση αναδρομής αλλά δε δουλέυε βλέπετε κάποιο λάθος? pa είναι ο πίνακας στον οποίο αποθηκέυονται οι αριθοί (10 για βομβα,9 αμα το κουτί που επιλέξει ο χρήστης δεν έχει τριγύρο βομβες και ένας αριθμος απο το 1 μεχρι το 8 ανάλογα με το πόσες βομβεσ έχει τριγυρο),pb ειναι ενας πινακς που γεμιζει με 1 και με 0,1 για τα ανοιχτα κουτια και 0 για τα κλειστα.nxm ειναι οι διαστάσεις του πίνακα και a,b oi συντεταγμένες που έχει επιλέξει ο χρήστης. > int anadromh(int **pa, int **pb, int n, int m, int a, int { if(a<0 || a>n-1 || b<0 || b>m-1 || pa[a][b]==10)//gia na mhn paei sta oria h se vomva { return 0; } if(pa[a][b]!=10 && pa[a][b]!=0 && pa[a][b]!=9) { pb[a][b]=1; return 0; } else { pb[a][b]=1; anadromh(pa,pb,n,m,a-1,; anadromh(pa,pb,n,m,a,b+1); anadromh(pa,pb,n,m,a+1,; anadromh(pa,pb,n,m,a,b-1); } return 1; }
Timonkaipumpa Δημοσ. 30 Απριλίου 2011 Δημοσ. 30 Απριλίου 2011 Δεν μπορώ να καταλάβω (και δεν ψήνομαι να κάτσω να καταλάβω) τι είναι το a, το b, c, pa και pb. Επίσης, θα σε βοηθούσε και εσένα καλύτερα να βάζεις ονόματα που να σημαίνουν κάτι στις μεταβλητές. Ακόμα, δεν κατάλαβα αυτή την συνάρτηση τι την θες. Εάν θες να προσομοιώσεις την λειτουργία του ναρκαλιευτή όπου ανοίγουν τα πλαϊνά κουτιά, τότε φτιάξε μία μόνο συνάρτηση όπου θα παίρνει σαν όρισμα τον πίνακα και το κελί που θες να ανοίξεις. Έτσι, εάν ο χρήστης επιλέξει να ανοίξει όλα τα πλαϊνά κελιά, θα καλείται αυτή η συνάρτηση με τις συντεταγμένες του κάθε πλαϊνού κελιού. Εάν πάλι είναι απαίτηση της άσκησης να χρησιμοποιήσεις αναδρομή... ένας γρήγορος τρόπος που μου ήρθε τώρα είναι να παίρνει σαν όρισμα η συνάρτηση μία συντεταγμένη που θες να ανοίξεις και τον πίνακα. Έτσι, μέχρι να εξαντληθούν τα γύρω κουτιά θα χρησιμοποιείται, σε "φάση" αναδρομής, η συνάρτηση αυτή.
personGR Δημοσ. 4 Μαΐου 2011 Δημοσ. 4 Μαΐου 2011 Για να μην ανοίξω νέο θέμα, θα ποστάρω μία εντελώς ξεχωριστή απορία εδώ: Έχω γράψει τον παρακάτω απλό κώδικα, αλλά όταν προσπαθώ για debug στο v.studio '08 μου βγάζει "Run-Time Check Failure #2 - Stack around the variable 'string' was corrupted.". Ξέρει κανείς γιατί συμβαίνει αυτό; >#include <stdio.h> #include <stdlib.h> void code(char *string) { int i; for (i=0;i<=4;i++) string[i] = string[i]+13; } main() { char string[5]; printf("Dwse seira xaraktirwn (5 gramamata/pshfia)\n"); scanf("%s",string); code(string); printf("to kwdikopoihmeno string einai %s\n",string); system("pause"); }
παπι Δημοσ. 4 Μαΐου 2011 Δημοσ. 4 Μαΐου 2011 βαλε string[100]. Λογικα δεν ειχει χωρο να βαλει το linefeed char
migf1 Δημοσ. 8 Μαΐου 2011 Δημοσ. 8 Μαΐου 2011 (επεξεργασμένο) Βασικά όλα τα strings στη C πρέπει να τερματίζονται με το null-character '\0' (που ισούται με 0). Είναι θεμελιώδης προϋπόθεση που την ελέγχουν όλες οι built-in συναρτήσεις της γλώσσας, ώστε να προσδιορίζουν που τελειώνει το κάθε string. Οπότε όταν δηλώνεις ένα string πρέπει να έχεις πάντα υπόψη σου πως η τελευταία του θέση ΠΡΕΠΕΙ να δεσμευτεί για τον μηδενικό χαρακτήρα. Το πρόβλημα στον κώδικά σου προκύπτει από το = που έχεις βάλει μέσα στη συνθήκη του for-loop, στη συνάρτηση code(), γιατί πας και αλλάζεις ΚΑΙ τον τελευταίο χαρακτήρα του string σου. Άλλαξε τη συνθήκη σε... >for (i=0;i<4;i++) Επίσης θα σου συνιστούσα όταν απλά θες να διαβάσεις ένα string να χρησιμοποιείς την συνάρτηση char * fgets (char *s, int count, FILE *stream) η οποία απαιτεί να της περάσεις ως παράμετρο και το μέγιστο μήκος του string που θέλεις να διαβάσει. Θα διαβάσει μέχρι (count-1) χαρακτήρες και τον τελευταίο θα τον μηδενίσει πριν σου επιστρέψει το string. Έκανα αλλαγές στον κώδικά σου ώστε να δουλεύει σωστά, ακόμα κι αν ο χρήστης πληκτρολογήσει περισσότερους από τους 5 χαρακτήρες που του βάζεις ως όριο (το οποίο btw θα έπρεπε να ήταν 4, για να μείνει χώρος και για τον μηδενικό χαρακτήρα στο τέλος). Στον κώδικα έχω γράψει και μια συνάρτηση char *s_get(char *s, int len) που τη χρησιμοποιώ για να διαβάζω το string, αντί της scanf(). Βασικά μιμείται τη λειτουργία της fgets(), με τη διαφορά πως διαβάζει μόνο από το πληκτρολόγιο κι επίσης δεν διατηρεί το ENTER στο τέλος του string (η fgets() διατηρεί το ENTER, συν ότι μπορεί να διαβάσει το string κι από αρχείο). Βασικά η s_get() που σου έγραψα στον κώδικα βελτιώνει τη λειτουργικότητα της στάνταρ συνάρτησης char * gets (char *s) στο ότι απαιτεί να της περάσεις ως παράμετρο και το μέγιστο πλήθος χαρακτήρων που θέλεις να διαβάσει (διαβάζει μέχρι len-1 χαρακτήρες και μηδενίζει τον τελευταίο πριν σου επιστρέψει το string). Έπειτα, στην main() έβαλα έναν έξτρα έλεγχο με ένα do-while loop, το οποίο ζητάει από την χρήστη να πληκτρολογήσει ένα string όσο εκείνος αντί για string πατάει σκέτο ENTER. Ακόμα, στην αρχή του κώδικα όρισα μια σταθερά STRLEN για το μέγιστο μήκος του string, την οποία και χρησιμοποιώ μετά στον υπόλοιπο κώδικα (οπότε αν θελήσεις να διαβά΄ζεις μεγαλύτερα ή μικρότερα strings αργότερα, θα αλλάξεις μονάχα αυτή τη σταθερά. Και τέλος, άλλαξα τον κώδικα της code() ώστε να χρησιμοποιεί pointer (αντί του int i που είχε ο αρχικός). Με pointers έχω γράψει και τον κώδικά της s_get() μιας και αυτή είναι βέλτιστη υλοποίηση για ταχύτητα εκτέλεσης Παραθέτω τον κώδικα ολοκληρωμένο... > #include <stdio.h> #define STRLEN 4+1 /* η τελευταία θέση είναι για το '\0' */ /* ------------------------------- * Διαβάζει χαρακτήρες από το πληκτρολόγιο μέχρι να πατηθεί το ENTER * βάζοντας τους πρωτους (len-1) στο sting s (ή λιγότερους αν το ENTER * πατηθεί νωρίτερα). Μηδενίζει τον τελευταίο κι επιστρέφει το string s */ char *s_get(char *s, int len) { char *cp; fflush(stdin); /* καθαρίζει το input buffer πριν διαβάσει */ for (cp=s; (*cp=getc(stdin)) != '\n' && (cp-s) < len-1; cp++ ) ; /* for-loop με κενό σώμα */ *cp = 0; /* μηδενίζει τον τελευταίο χαρακτήρα */ return s; } /* ------------------------------- */ void code(char *s) { char *cp; for (cp=s; *cp; cp++) *cp += (char)13; return; } /* ------------------------------- */ int main(void) { char string[sTRLEN]; /* ο τελευταίος χαρακτήρας ΠΡΕΠΕΙ να είναι '\0' */ do { printf("Dwse seira xaraktirwn (%d gramamata/pshfia): ", STRLEN-1); s_get(string, STRLEN); } while ( !(*string) ); /* ισοδυναμεί με: } while( string[0] != '\0' ); */ code(string); printf("to kwdikopoihmeno string einai %s\n",string); system("pause"); /* καλύτερα να αλλαχτεί σε: getchar(); */ return 0; } Για να μην ανοίξω νέο θέμα, θα ποστάρω μία εντελώς ξεχωριστή απορία εδώ: Έχω γράψει τον παρακάτω απλό κώδικα, αλλά όταν προσπαθώ για debug στο v.studio '08 μου βγάζει "Run-Time Check Failure #2 - Stack around the variable 'string' was corrupted.". Ξέρει κανείς γιατί συμβαίνει αυτό; >#include <stdio.h> #include <stdlib.h> void code(char *string) { int i; for (i=0;i<=4;i++) string[i] = string[i]+13; } main() { char string[5]; printf("Dwse seira xaraktirwn (5 gramamata/pshfia)\n"); scanf("%s",string); code(string); printf("to kwdikopoihmeno string einai %s\n",string); system("pause"); } Επεξ/σία 8 Μαΐου 2011 από migf1
personGR Δημοσ. 8 Μαΐου 2011 Δημοσ. 8 Μαΐου 2011 migf1 σε ευχαριστώ με βοήθησες πολύ με τις συμβουλές σου!
migf1 Δημοσ. 8 Μαΐου 2011 Δημοσ. 8 Μαΐου 2011 Παρακαλώ, χαίρομαι που σε βοήθησε Έκανα λίγο edit τον παραπάνω κώδικα, βασικά προσέθεσα μερικά παραπάνω σχόλια κι άλλαξα ελαφρώς τη σειρά των s και cp μέσα στην s_gets() απλά για να είναι λίγο πιο συνεπής με την τεκμηρίωση που γράφω στην αρχή της συνάρτησης. Και δυο ακόμα σχόλια: α) πολλοί λένε να μη χρησιμοποιείτε την fflush() γιατί δεν υποστηρίζεται από όλους τους compilers, παρόλο που αποτελεί στάνταρ συνάρτηση. Προσωπικά δεν έχω βρει ακόμα σοβαρό compiler που να μη την υποστηρίζει. Όπως και να έχει το σίγουρο είναι πως αντιμετωπίζει το άλλο Ι/O πρόβλημα, κατά το οποίο δεν καθαρίζεται το input buffer μετά τη χρήση κάποιων στάνταρ συναρτήσεων της βιβλιοθήκης stdio (εξαρτάται και από τη πλατφόρμα). β) η συνάρτηση system(pause) που χρησιμοποιείς στο τέλος του κώδικα δεν ανήκει στις στάνταρ συναρτήσεις της C, οπότε άμα πας να κάνεις compile τον κώδικα σε άλλη πλατφόρμα, ενδέχεται να σου βγάλει σφάλμα. H getchar() που σου προτείνω μέσα στο σχόλιο (πριν λίγο το έβαλα) κάνει (σχεδόν) την ίδια δουλειά και είναι συμβατή με όλες τις πλατφόρμες .
personGR Δημοσ. 11 Μαΐου 2011 Δημοσ. 11 Μαΐου 2011 @migf1, thanks για μια φορά. Λοιπόν, άλλη μια απορία. Η δουλειά του παρακάτω κώδικα είναι να προκαλεί τη μετάθεση ενός Α(ν,μ) σε έναν Β(μ.ν) πίνακα. Το θέμα είναι πως μου βγάζει "0xcdcdcdcd" σφάλμα όταν ν!=μ, λειτουργεί δηλαδή μόνο για τετραγωνικούς πίνακες! Επειδή είναι η πρώτη φορά όμως που χρησιμοποιώ την malloc δεν ξέρω τι πάει στραβά! Αν κάποιος ξέρει τι γίνεται, pls ας βοηθήσει!! > #include <stdio.h> #include <stdlib.h> main() { int i,j,t,k; int** A; int** B; printf("Dwse arithmo grammwn, sthlwn\n"); scanf("%d%d",&i,&j); A =(int**)malloc(i*sizeof(int*)); B =(int**)malloc(j*sizeof(int*)); for(t = 0; t < j; t++) { A[t] =(int*) malloc(j * sizeof(int)); } for(k = 0; k < i ; k++) { B[k] = (int*) malloc(i * sizeof(int)); } for(t=0;t<i;++t){ for(k=0;k<j;++k){ printf("Dwse to stoixeio ths %dhs grammhs kai %dhs sthlhs\n",t+1,k+1); scanf("%d",&A[t][k]); }} for(t=0;t<i;++t){ for(k=0;k<j;++k){ B[k][t] = A[t][k]; }} for(t=0;t<i;++t){ for(k=0;k<j;++k){ printf("%d",A[t][k]); }} printf("\n"); for(t=0;t<j;++t){ for(k=0;k<i;++k){ printf("%d",B[t][k]); }} getchar(); }
παπι Δημοσ. 11 Μαΐου 2011 Δημοσ. 11 Μαΐου 2011 0xcdcdcdcd == καποια μεταβλητη παει να χρησιμοποιηθει χωρις να εχει αρχικοποιηθει (σε MS stdudio να φανταστω) τσεκαρε αυτο
personGR Δημοσ. 11 Μαΐου 2011 Δημοσ. 11 Μαΐου 2011 0xcdcdcdcd == καποια μεταβλητη παει να χρησιμοποιηθει χωρις να εχει αρχικοποιηθει (σε MS stdudio να φανταστω) τσεκαρε αυτο Αλήθεια; Λες το θέμα να το προκαλούν οι πίνακες μέσω της malloc; Πάντως στο v.studio όταν κάνω debug το πρόβλημα μου το βγάζει στην εντολή του τέταρτου for και το παράθυρο Autos μου βγάζει "B[k] ......Cxx0030:error: expression cannot be evaluated". Δεν έχω ιδέα περί τίνος πρόκειται!
migf1 Δημοσ. 11 Μαΐου 2011 Δημοσ. 11 Μαΐου 2011 @migf1, thanks για μια φορά. Λοιπόν, άλλη μια απορία. Η δουλειά του παρακάτω κώδικα είναι να προκαλεί τη μετάθεση ενός Α(ν,μ) σε έναν Β(μ.ν) πίνακα. Το θέμα είναι πως μου βγάζει "0xcdcdcdcd" σφάλμα όταν ν!=μ, λειτουργεί δηλαδή μόνο για τετραγωνικούς πίνακες! Επειδή είναι η πρώτη φορά όμως που χρησιμοποιώ την malloc δεν ξέρω τι πάει στραβά! Αν κάποιος ξέρει τι γίνεται, pls ας βοηθήσει!! [snip] Δώσε μου λίγο χρόνο να... καθαρόγράψω τον κώδικά σου, ώστε να καταλάβω τι ακριβώς κάνει. Γιατί δεν μπορώ να τον διαβάσω έτσι (δεν έχω συνηθίσει καθόλου σε αυτό το στυλ γραφής ) EDIT: Βασικά τα 'χεις κάνει... ρόιδο Αν σου φτιάξω τον κώδικα με επεξηγηματικά σχόλια να δουλεύει, υπόσχεσαι πως θα τον μελετήσεις και δεν θα τον παραδώσεις έτοιμο; Βασικά θες να διαβάζεις έναν πίνακα A(m,n) και να φτιάχνεις έναν B(n,m) ; Να κάνεις δηλαδή τις στήλες γραμμές και τις γραμμές στήλες;
personGR Δημοσ. 11 Μαΐου 2011 Δημοσ. 11 Μαΐου 2011 Δώσε μου λίγο χρόνο να... καθαρόγράψω τον κώδικά σου, ώστε να καταλάβω τι ακριβώς κάνει. Γιατί δεν μπορώ να τον διαβάσω έτσι (δεν έχω συνηθίσει καθόλου σε αυτό το στυλ γραφής ) EDIT: Βασικά τα 'χεις κάνει... ρόιδο Αν σου φτιάξω τον κώδικα με επεξηγηματικά σχόλια να δουλεύει, υπόσχεσαι πως θα τον μελετήσεις και δεν θα τον παραδώσεις έτοιμο; Βασικά θες να διαβάζεις έναν πίνακα A(m,n) και να φτιάχνεις έναν B(n,m) ; Να κάνεις δηλαδή τις στήλες γραμμές και τις γραμμές στήλες; Εννοείται ρε συ, γι'αυτό πόσταρα στο thread in the first place. :D (παρεπιπτόντως, αυτό ακριβώς καλούμαι να κάνω, αλλά να τονίσω ότι πρέπει ο χρήστης να δίνει τις διαστάσεις και τα στοιχεία του Α)
migf1 Δημοσ. 11 Μαΐου 2011 Δημοσ. 11 Μαΐου 2011 Ναι το κατάλαβα για τις διαστάσεις, γιατί προφανώς θέλει να σας μάθει τη χρήση της malloc (αν και με το C99 στανταρ η C υποστηρίζει πλέον εγγενώς πίνακες μεταβλητού μεγέθους απευθείας στον ορισμό τους, αλλά ok). Για την χειροκίνητη εισαγωγή στοιχείων, εγώ θα το βάλω να κάνει generate αυτόματα τιμές στην A και φτιάξτο μετά εσύ με scanf(). EDIT: Τελικά είναι πιο παλούκι από ότι νόμιζα !!!!! Υπάρχει μήπως έτοιμος ο μαθηματικός τύπος που κάνει την αντιμετάθεση; Επίσης, είναι σίγουρο πως πρέπει να δουλεύει και σε μη τετράγωνους πίνακες; Γιατί αν είναι μόνο για τετράγωνους, τότε είναι εύκολο (αλλιώς είναι πολύ δύσκολο, μου χει βγάλει το λάδι )
personGR Δημοσ. 11 Μαΐου 2011 Δημοσ. 11 Μαΐου 2011 Ναι το κατάλαβα για τις διαστάσεις, γιατί προφανώς θέλει να σας μάθει τη χρήση της malloc (αν και με το C99 στανταρ η C υποστηρίζει πλέον εγγενώς πίνακες μεταβλητού μεγέθους απευθείας στον ορισμό τους, αλλά ok). Για την χειροκίνητη εισαγωγή στοιχείων, εγώ θα το βάλω να κάνει generate αυτόματα τιμές στην A και φτιάξτο μετά εσύ με scanf(). EDIT: Τελικά είναι πιο παλούκι από ότι νόμιζα !!!!! Υπάρχει μήπως έτοιμος ο μαθηματικός τύπος που κάνει την αντιμετάθεση; Όχι απ'όσο ξέρω, και δε νομίζω η C να έχει ενσωματωμένη συνάρτηση για αυτή τη δουλειά όπως το Matlab!! Όχι, θέλει για κάθε πίνακα γιατί στην εκφώνηση η άσκηση προκαλεί τον χρήστη να δώσει διαστάσεις 3x4 :/
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα