Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλησπερα κανω μια ασκηση στη 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 );

γιατι εχω αυτην την εξοδο?

 

post-302620-0-58684900-1512494310_thumb.png

 

Μηπως τρεχει κατι με τα cast?

Δημοσ.

γιατι κάνεις cast Σε int? ποιος ο λογος; δεν ρωταω κοροιδευτικα, απλα θελω να μαθω τι σκεφτεσαι

εχω σκεφτει μια λυση που αν ειναι το ιδιο μεγεθος τα στρινγκ και τα ταξινομησω με βαση το ascii  αν ειναι οντως ειναι αναγραμματισμος τα 2 στρινγκ μετα θα ειναι ακριβως τα ιδια

 

Βάζεις το str0 μέσα στο out0, αλλά ξεχνάς τον τερματικό χαρακτήρα. Μετά την for κάνε:

out0[i] = '\0';

θα το δοκιμασω σε λιγο και θα σου πω.

Δημοσ.

εχω σκεφτει μια λυση που αν ειναι το ιδιο μεγεθος τα στρινγκ και τα ταξινομησω με βαση το ascii  αν ειναι οντως ειναι αναγραμματισμος τα 2 στρινγκ μετα θα ειναι ακριβως τα ιδια

 

Σωστή σκέψη, απλά να ξέρεις ότι υπάρχουν και άλλοι, ευκολότεροι τρόποι να τα συγκρίσεις χωρίς καν να τα ταξινομήσεις ;)

Counting sort

Δημοσ.

εχω σκεφτει μια λυση που αν ειναι το ιδιο μεγεθος τα στρινγκ και τα ταξινομησω με βαση το ascii  αν ειναι οντως ειναι αναγραμματισμος τα 2 στρινγκ μετα θα ειναι ακριβως τα ιδια

θα το δοκιμασω σε λιγο και θα σου πω.

αν ειναι ιδιο μεγεθος εννοεις μαλλον το αθροισμα των ASCII χαρακτηρων μιας λεξης ; Αν το "PQ" ειναι ενα στρινγκ τοτε το αθροισμα τους θα ειναι 80 + 81 = 161 , επισης το στρινγκ "ΟR" ειναι και αυτο 79 + 82 = 161 αλλα απο οσο βλεπεις δεν ειναι ιδια τα στρινγκς. Επισης αν εχεις δυο char μεταβλητες και τις συγκρινεις, γινεται η συγκριση με βασει τον ASCII ουτως ή αλλως, δεν χρειαζεσαι να κανεις cast σε Int. Αν καταλαβα κατι λαθος ή ειμαι καπου λαθος ας με διορθωσουν γιατι κ εγω noob ειμαι :)

Δημοσ.

Σωστή σκέψη, απλά να ξέρεις ότι υπάρχουν και άλλοι, ευκολότεροι τρόποι να τα συγκρίσεις χωρίς καν να τα ταξινομήσεις ;)

Counting sort

Θα δοκιμασω τη δικη μου,με την προσθηκη σου, πρωτα και αν δεν βγει θα δοκιμασω αυτο :)

αυτο που μου ειπες το βαζω εξω με την for για να μπει στο τελευταιο cell σωστα?

 

EDIT: Το δοκιμασα και δεν αλλαξε τιποτα.

Δημοσ.

Α, το βρήκα το πρόβλημα. Ουσιαστικά, κάνεις bubblesort όλο το str0, αλλά απ' ότι καταλαβαίνω μαζί με τον τερματικό χαρακτήρα και μαζί με άλλους χαρακτήρες που δεν είχες αρχικοποιήσει. Πρέπει να χρησιμοποιήσεις το μέγεθος της γραμμής μέσα στο bubblesort που έχεις κάνει, όχι το μέγεθος του πίνακα. Για παράδειγμα:

 

len = strlen(str0);
 
for(j=1; j<len; j++)
{for(k=0; k<len-j; k++){
  • Like 1
Δημοσ. (επεξεργασμένο)

 

Α, το βρήκα το πρόβλημα. Ουσιαστικά, κάνεις bubblesort όλο το str0, αλλά απ' ότι καταλαβαίνω μαζί με τον τερματικό χαρακτήρα και μαζί με άλλους χαρακτήρες που δεν είχες αρχικοποιήσει. Πρέπει να χρησιμοποιήσεις το μέγεθος της γραμμής μέσα στο bubblesort που έχεις κάνει, όχι το μέγεθος του πίνακα. Για παράδειγμα:

len = strlen(str0);
 
for(j=1; j<len; j++)
{for(k=0; k<len-j; k++){

Απο την εκφωνηση μας δινεται Μπορείτε να υποθέσετε ότι κάθε γραμμή εισόδου έχει το πολύ 200 χαρακτήρες.

Και απλα υπεθεσα οτι ολα τα υπολοιπα κελια θα ειναι κενα.Δοκιμαζω

EDIT:Δοκιμασα και τα εμφανιζει σαν χαρακτηρες (επιτελους :P )απλα

1.σε μια γραμμη δεν εβγαλε καν την αντιστοιχη με κεφαλαια

post-302620-0-51096600-1512497795_thumb.png

2.Πως γινεται να "κρατησω"  το string χωρις το κενο στην αρχη?Απο οτι καταλαβα η συγκεκριμενη ταξινομηση "βαζει" τα κενα στην αρχη.

Επεξ/σία από matheostsik
Δημοσ.

1. Δε ξέρω πώς είναι ο κώδικας μετά τις αλλαγές, οπότε δε μπορώ να ξέρω πού είναι το πρόβλημα.

2. Πριν αντιγράψεις το str0 στο out0, αγνόησε τα κενά με μια παραπάνω for, και άρχισε να το αντιγράφεις από τον πρώτο χαρακτήρα που δεν είναι κενό.

  • Like 1
Δημοσ.

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)

post-302620-0-77379400-1512502838_thumb.png

Οι εισοδοι που χρησιμοποιηω:

aaaaa

aa

aaa

 

aaaaa

a a

a aa

 

Δημοσ.

 

		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.

  • Like 1
Δημοσ.

Αυτό δεν θα έπρεπε να είναι k<len0 ?

 

 

Δεν είναι πιο δόκιμο να ελέγχεις αν το len0 και το len1 είναι ίδια ? Αν δεν είναι ίδια αποκλείεται να είναι ίδιες λέξεις οπότε παίρνεις δρόμο και γλυτώνεις τα τεράστια for.

 

Από εκεί και πέρα, εφόσον len0 == len1, δεν μπορεί να ενσωματωθεί η ταξινόμηση και των δύο strings σε ένα μόνο σετ από for αντί για δύο ολόιδια ?

1.Αυτο που λες ειχα δοκιμασει στην αρχη αλλα μετα καταλαβα οτι δε παιζει γιατι

πχ ααα != α αα

το οποιο ειναι αναγραμματισμος,αρε δε με βοηθαει.

2.Ναι μπορει αλλα δεν νομιζω να αλλαξει κατι σχετικα με τις εξοδους,σωστα?

Δημοσ.

1.Αυτο που λες ειχα δοκιμασει στην αρχη αλλα μετα καταλαβα οτι δε παιζει γιατι

πχ ααα != α αα

το οποιο ειναι αναγραμματισμος,αρε δε με βοηθαει.

Τα "aaa " και "a aa" είναι όντως αναγραμματισμοί αλλά έχουν και τα δύο 4 χαρακτήρες οπότε πληρούν την συνθήκη.

 

Η άσκηση σου ζητάει να δίνεις αποτέλεσμα σωστού για τα strings "aaa" (χωρίς κενό πουθενά δηλαδή 3 χαρακτήρες) και "a aa" ? Πολύ παράξενο μου φαίνεται.

Δημοσ.

Και πάλι ξέχασες να θέσεις το τελευταίο χαρακτήρα ως '\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;
}

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...