matheostsik Δημοσ. 5 Δεκεμβρίου 2017 Δημοσ. 5 Δεκεμβρίου 2017 Καλησπερα κανω μια ασκηση στη C για τη σχολη μου που με λιγα λογια πρεπει να εισαγω 2 files τα των οποιων καθε γραμμη συγκρινεται αν ειναι ή οχι αναγραμματισμος της αλλης.Εχω φτιαξει ενα προγραμμα που νομιζω οτι δουλευει απλα πρεπει να διορθωσω καποια σημεια.Αν χρειαστει κιαλλα κομματια κωδικα πειτε μου Παραθετω το κομματι κωδικα της ερωτησης: puts(str0); for(j=1; j<200; j++) {for(k=0; k<200-j; k++){ if((int)str0[k]>=(int)str0[k+1]){ temp=str0[k]; str0[k]=str0[k+1]; str0[k+1]=temp; } } } for (i = 0; str0[i] != '\0'; i++) { out0[i] = toupper(str0[i]); } printf("%s\n",out0 ); γιατι εχω αυτην την εξοδο? Μηπως τρεχει κατι με τα cast?
Aggeluska Δημοσ. 5 Δεκεμβρίου 2017 Δημοσ. 5 Δεκεμβρίου 2017 γιατι κάνεις cast Σε int? ποιος ο λογος; δεν ρωταω κοροιδευτικα, απλα θελω να μαθω τι σκεφτεσαι 1
GReaperEx Δημοσ. 5 Δεκεμβρίου 2017 Δημοσ. 5 Δεκεμβρίου 2017 Βάζεις το str0 μέσα στο out0, αλλά ξεχνάς τον τερματικό χαρακτήρα. Μετά την for κάνε: out0[i] = '\0'; 2
matheostsik Δημοσ. 5 Δεκεμβρίου 2017 Μέλος Δημοσ. 5 Δεκεμβρίου 2017 γιατι κάνεις cast Σε int? ποιος ο λογος; δεν ρωταω κοροιδευτικα, απλα θελω να μαθω τι σκεφτεσαι εχω σκεφτει μια λυση που αν ειναι το ιδιο μεγεθος τα στρινγκ και τα ταξινομησω με βαση το ascii αν ειναι οντως ειναι αναγραμματισμος τα 2 στρινγκ μετα θα ειναι ακριβως τα ιδια Βάζεις το str0 μέσα στο out0, αλλά ξεχνάς τον τερματικό χαρακτήρα. Μετά την for κάνε: out0[i] = '\0'; θα το δοκιμασω σε λιγο και θα σου πω.
GReaperEx Δημοσ. 5 Δεκεμβρίου 2017 Δημοσ. 5 Δεκεμβρίου 2017 εχω σκεφτει μια λυση που αν ειναι το ιδιο μεγεθος τα στρινγκ και τα ταξινομησω με βαση το ascii αν ειναι οντως ειναι αναγραμματισμος τα 2 στρινγκ μετα θα ειναι ακριβως τα ιδια Σωστή σκέψη, απλά να ξέρεις ότι υπάρχουν και άλλοι, ευκολότεροι τρόποι να τα συγκρίσεις χωρίς καν να τα ταξινομήσεις Counting sort
Aggeluska Δημοσ. 5 Δεκεμβρίου 2017 Δημοσ. 5 Δεκεμβρίου 2017 εχω σκεφτει μια λυση που αν ειναι το ιδιο μεγεθος τα στρινγκ και τα ταξινομησω με βαση το ascii αν ειναι οντως ειναι αναγραμματισμος τα 2 στρινγκ μετα θα ειναι ακριβως τα ιδια θα το δοκιμασω σε λιγο και θα σου πω. αν ειναι ιδιο μεγεθος εννοεις μαλλον το αθροισμα των ASCII χαρακτηρων μιας λεξης ; Αν το "PQ" ειναι ενα στρινγκ τοτε το αθροισμα τους θα ειναι 80 + 81 = 161 , επισης το στρινγκ "ΟR" ειναι και αυτο 79 + 82 = 161 αλλα απο οσο βλεπεις δεν ειναι ιδια τα στρινγκς. Επισης αν εχεις δυο char μεταβλητες και τις συγκρινεις, γινεται η συγκριση με βασει τον ASCII ουτως ή αλλως, δεν χρειαζεσαι να κανεις cast σε Int. Αν καταλαβα κατι λαθος ή ειμαι καπου λαθος ας με διορθωσουν γιατι κ εγω noob ειμαι
matheostsik Δημοσ. 5 Δεκεμβρίου 2017 Μέλος Δημοσ. 5 Δεκεμβρίου 2017 Σωστή σκέψη, απλά να ξέρεις ότι υπάρχουν και άλλοι, ευκολότεροι τρόποι να τα συγκρίσεις χωρίς καν να τα ταξινομήσεις Counting sort Θα δοκιμασω τη δικη μου,με την προσθηκη σου, πρωτα και αν δεν βγει θα δοκιμασω αυτο αυτο που μου ειπες το βαζω εξω με την for για να μπει στο τελευταιο cell σωστα? EDIT: Το δοκιμασα και δεν αλλαξε τιποτα.
GReaperEx Δημοσ. 5 Δεκεμβρίου 2017 Δημοσ. 5 Δεκεμβρίου 2017 Α, το βρήκα το πρόβλημα. Ουσιαστικά, κάνεις bubblesort όλο το str0, αλλά απ' ότι καταλαβαίνω μαζί με τον τερματικό χαρακτήρα και μαζί με άλλους χαρακτήρες που δεν είχες αρχικοποιήσει. Πρέπει να χρησιμοποιήσεις το μέγεθος της γραμμής μέσα στο bubblesort που έχεις κάνει, όχι το μέγεθος του πίνακα. Για παράδειγμα: len = strlen(str0); for(j=1; j<len; j++) {for(k=0; k<len-j; k++){ 1
matheostsik Δημοσ. 5 Δεκεμβρίου 2017 Μέλος Δημοσ. 5 Δεκεμβρίου 2017 (επεξεργασμένο) Α, το βρήκα το πρόβλημα. Ουσιαστικά, κάνεις bubblesort όλο το str0, αλλά απ' ότι καταλαβαίνω μαζί με τον τερματικό χαρακτήρα και μαζί με άλλους χαρακτήρες που δεν είχες αρχικοποιήσει. Πρέπει να χρησιμοποιήσεις το μέγεθος της γραμμής μέσα στο bubblesort που έχεις κάνει, όχι το μέγεθος του πίνακα. Για παράδειγμα: len = strlen(str0); for(j=1; j<len; j++) {for(k=0; k<len-j; k++){ Απο την εκφωνηση μας δινεται Μπορείτε να υποθέσετε ότι κάθε γραμμή εισόδου έχει το πολύ 200 χαρακτήρες. Και απλα υπεθεσα οτι ολα τα υπολοιπα κελια θα ειναι κενα.Δοκιμαζω EDIT:Δοκιμασα και τα εμφανιζει σαν χαρακτηρες (επιτελους )απλα 1.σε μια γραμμη δεν εβγαλε καν την αντιστοιχη με κεφαλαια 2.Πως γινεται να "κρατησω" το string χωρις το κενο στην αρχη?Απο οτι καταλαβα η συγκεκριμενη ταξινομηση "βαζει" τα κενα στην αρχη. Επεξ/σία 5 Δεκεμβρίου 2017 από matheostsik
GReaperEx Δημοσ. 5 Δεκεμβρίου 2017 Δημοσ. 5 Δεκεμβρίου 2017 1. Δε ξέρω πώς είναι ο κώδικας μετά τις αλλαγές, οπότε δε μπορώ να ξέρω πού είναι το πρόβλημα. 2. Πριν αντιγράψεις το str0 στο out0, αγνόησε τα κενά με μια παραπάνω for, και άρχισε να το αντιγράφεις από τον πρώτο χαρακτήρα που δεν είναι κενό. 1
matheostsik Δημοσ. 5 Δεκεμβρίου 2017 Μέλος Δημοσ. 5 Δεκεμβρίου 2017 1. Δε ξέρω πώς είναι ο κώδικας μετά τις αλλαγές, οπότε δε μπορώ να ξέρω πού είναι το πρόβλημα. 2. Πριν αντιγράψεις το str0 στο out0, αγνόησε τα κενά με μια παραπάνω for, και άρχισε να το αντιγράφεις από τον πρώτο χαρακτήρα που δεν είναι κενό. while (1) { if ((fgets(str0,200, filep0) == NULL)||(fgets(str1,200, filep1) == NULL)){ break;} puts(str0); puts(str1); len0= strlen(str0); for(j=1; j<len0; j++) {for(k=0; k<len1-j; k++){ if((int)str0[k]>=(int)str0[k+1]){ temp=str0[k]; str0[k]=str0[k+1]; str0[k+1]=temp; } } } i=0; do{ if(str0[i] != ' '){ out0[m] = toupper(str0[i]); m++; } i++; }while(str0[i] != '\0'); puts(out0); len1=strlen(str1); for(j1=1; j1<len1; j1++){ for(k1=0; k1<len1-j1; k1++) { if((int)str1[k1]>=(int)str1[k1+1]) { temp1=str1[k1]; str1[k1]=str1[k1+1]; str1[k1+1]=temp1; } } } q=0; for(i=0;str1[i] != '\0';i++){ if(str1[i] != ' '){ out1[q] = toupper(str1[i]); q++; } } puts(out1); } Εκανα μια προσπαθεια να μη κρατησω τα κενα αλλα και παλι δεν εχω τις εξοδους που θελω (line58 kai 81) Οι εισοδοι που χρησιμοποιηω: aaaaa aa aaa aaaaa a a a aa
imitheos Δημοσ. 5 Δεκεμβρίου 2017 Δημοσ. 5 Δεκεμβρίου 2017 for(j=1; j<len0; j++) {for(k=0; k<len1-j; k++){ Αυτό δεν θα έπρεπε να είναι k<len0 ? len0= strlen(str0); μεγάλα nested for για sort len1=strlen(str1); μεγάλα nested for για sort Δεν είναι πιο δόκιμο να ελέγχεις αν το len0 και το len1 είναι ίδια ? Αν δεν είναι ίδια αποκλείεται να είναι ίδιες λέξεις οπότε παίρνεις δρόμο και γλυτώνεις τα τεράστια for. Από εκεί και πέρα, εφόσον len0 == len1, δεν μπορεί να ενσωματωθεί η ταξινόμηση και των δύο strings σε ένα μόνο σετ από for αντί για δύο ολόιδια ? Offtopic: Στην παρούσα άσκηση δεν αξίζει το κόπο αλλά να αναφέρουμε εγκυκλοπαιδικά ότι εκτός από την μέθοδο με την ταξινόμηση και τον έλεγχο για ταύτιση, μια άλλη μέθοδος είναι αυτή του ιστογράμματος. Εφόσον μιλάμε για ascii, τότε έχεις μόλις 128 διαφορετικές τιμές που μπορεί να πάρει ο κάθε χαρακτήρας οπότε δεν είναι δύσκολο να ορίσεις ένα πίνακα με 128 θέσεις. int hist[128] = { 0 }; for (i = 0; i < len; i++ { hist[str0[i]]++; hist[str1[i]]--; } Χωρίς χρονοβόρες ταξινομήσεις και ifs και λοιπά, πας απλά και αυξάνεις την θέση του πίνακα για κάθε εμφάνιση ενός χαρακτήρα. Αν δηλαδή το string έχει 3 φορές το αγγλικό Α, τότε ο πίνακας θα έχει τιμή 3 στη θέση 65. Ομοίως μειώνεις κατά 1 την κάθε εμφάνιση του χαρακτήρα του δεύτερου string. Αν το ιστόγραμμά σου είναι στο τέλος μηδενικό σε όλες τις θέσεις, τότε σημαίνει ότι οι δύο λέξεις έχουν ακριβώς τα ίδια γράμματα. Αυτή η μέθοδος έχει το κακό ότι τρώει μνήμη γιατί χρειάζεσαι τόσο μεγάλο πίνακα όσο το εύρος των τιμών και επίσης στο τέλος πρέπει να ελέγχεις όλες αυτές τις θέσεις αν είναι μηδενικές. Δηλαδή αν έχεις το string "Hello" θα πρέπει να ορίσεις ένα πίνακα 128 θέσεων και να ψάξεις 128 θέσεις ενώ το string σου έχει μέγεθος μόλις 5. 1
matheostsik Δημοσ. 5 Δεκεμβρίου 2017 Μέλος Δημοσ. 5 Δεκεμβρίου 2017 Αυτό δεν θα έπρεπε να είναι k<len0 ? Δεν είναι πιο δόκιμο να ελέγχεις αν το len0 και το len1 είναι ίδια ? Αν δεν είναι ίδια αποκλείεται να είναι ίδιες λέξεις οπότε παίρνεις δρόμο και γλυτώνεις τα τεράστια for. Από εκεί και πέρα, εφόσον len0 == len1, δεν μπορεί να ενσωματωθεί η ταξινόμηση και των δύο strings σε ένα μόνο σετ από for αντί για δύο ολόιδια ? 1.Αυτο που λες ειχα δοκιμασει στην αρχη αλλα μετα καταλαβα οτι δε παιζει γιατι πχ ααα != α αα το οποιο ειναι αναγραμματισμος,αρε δε με βοηθαει. 2.Ναι μπορει αλλα δεν νομιζω να αλλαξει κατι σχετικα με τις εξοδους,σωστα?
imitheos Δημοσ. 5 Δεκεμβρίου 2017 Δημοσ. 5 Δεκεμβρίου 2017 1.Αυτο που λες ειχα δοκιμασει στην αρχη αλλα μετα καταλαβα οτι δε παιζει γιατι πχ ααα != α αα το οποιο ειναι αναγραμματισμος,αρε δε με βοηθαει. Τα "aaa " και "a aa" είναι όντως αναγραμματισμοί αλλά έχουν και τα δύο 4 χαρακτήρες οπότε πληρούν την συνθήκη. Η άσκηση σου ζητάει να δίνεις αποτέλεσμα σωστού για τα strings "aaa" (χωρίς κενό πουθενά δηλαδή 3 χαρακτήρες) και "a aa" ? Πολύ παράξενο μου φαίνεται.
GReaperEx Δημοσ. 5 Δεκεμβρίου 2017 Δημοσ. 5 Δεκεμβρίου 2017 Και πάλι ξέχασες να θέσεις το τελευταίο χαρακτήρα ως '\0'. Πήρα τον κώδικα σου, έκανα κάποιες μικροσκοπικές αλλαγές και τώρα δουλεύει. Αν έχεις κάποια απορία, ρώτα. Προσπάθησα να μην τον αλλάξω πολύ, απλά δε χρειάζεσαι όλες αυτές τις παραπανίσιες μεταβλητές. #include <stdio.h> #include <string.h> #include <ctype.h> int main(int argc, char* argv[]) { FILE *filep0, *filep1; char str0[200], str1[200]; char out0[200], out1[200]; int i, j, k; int index, len; char temp; filep0 = fopen(argv[1], "r"); filep1 = fopen(argv[2], "r"); while (1) { if ((fgets(str0,200, filep0) == NULL)||(fgets(str1,200, filep1) == NULL)) { break; } /* Ignore newline characters */ str0[strlen(str0) - 1] = '\0'; str1[strlen(str1) - 1] = '\0'; puts(str0); puts(str1); len= strlen(str0); for(j=1; j<len; j++) { for(k=0; k<len-j; k++) { if((int)str0[k]>=(int)str0[k+1]) { temp=str0[k]; str0[k]=str0[k+1]; str0[k+1]=temp; } } } index = 0; for(i=0; str1[i] != '\0'; i++) { if(str0[i] != ' ') { out0[index] = toupper(str0[i]); index++; } } out0[index] = '\0'; puts(out0); len=strlen(str1); for(j=1; j<len; j++) { for(k=0; k<len-j; k++) { if((int)str1[k]>=(int)str1[k+1]) { temp=str1[k]; str1[k]=str1[k+1]; str1[k+1]=temp; } } } index=0; for(i=0; str1[i] != '\0'; i++) { if(str1[i] != ' ') { out1[index] = toupper(str1[i]); index++; } } out1[index] = '\0'; puts(out1); } fclose(filep0); fclose(filep1); return 0; }
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα