migf1 Δημοσ. 13 Φεβρουαρίου 2012 Δημοσ. 13 Φεβρουαρίου 2012 (επεξεργασμένο) Επειδή δεν μου κάθεται πολύ καλά λόγω των malloc() μικρών ποσοτήτων, αλλά δεν μου έρχεται τώρα κάτι καλύτερο στο μυαλό (βασικά κάτι ταχύτερο, δεδομένου πως το c-string μπορεί να είναι πολύ μεγάλο), υπάρχει κάποια καλύτερη υλοποίηση κυκλικής μετατόπισης χαρακτήρων προς τα αριστερά ενός c-string από την παρακάτω; > char *s_shift_left( char *s, int shiftby, const int len ) { char *temp = NULL; /* if ( !s || shiftby < 0 || len < 1 ) return s; if ( shiftby > len-1 ) shiftby %= len; */ if ( !s || shiftby < 1 || len < 2 || (shiftby %= len) == 0 ) return s; if ( NULL == (temp = malloc( shiftby * sizeof(char) )) ) return s; memcpy( temp, s, shiftby * sizeof(char) ); memmove( s, &s[ shiftby ], (len-shiftby) * sizeof(char) ); memcpy( &s[ len-shiftby ], temp, shiftby * sizeof(char) ); free( temp ); return s; } Παραδείγματα: > char *s = "abcde"; s_shift_left( s, 1, strlen(s) ); // δίνει: "bcdea" > char *s = "abcde"; s_shift_left( s, 2, strlen(s) ); // δίνει: "cdeab" > char *s = "abcde"; s_shift_left( s, 5, strlen(s) ); // δίνει: "abcde" > char *s = "abcde"; s_shift_left( s, -1, ... ); // δίνει: "abcde" > char *s = "abcde"; s_shift_left( s, 25600, 0); // δίνει: "abcde" EDIT: Βελτίωση της αρχικής συνθήκης, κατόπιν εύστοχης παρατήρησης του φίλου nilos_gr! Σε σχόλια ο παλιός κώδικας. (τελικά το αφήνουμε με το malloc() ως η ταχύτερη δυνατή υλοποίηση; ) Επεξ/σία 13 Φεβρουαρίου 2012 από migf1
nilosgr Δημοσ. 13 Φεβρουαρίου 2012 Δημοσ. 13 Φεβρουαρίου 2012 len ειναι το μηκος του s στο οποιο θα "επεξεργαστεις", ε; Τοτε το: >if ( shiftby > len-1 ) shiftby %= len; δεν επρεπε να παει πριν το αλλο if, ωστε αν (shiftby %= len) == 0 να αποφυγεις ολη τα φασαρια; EDIT: Ισως καλυτερα ετσι: >if (!s || len <= 1 ) return s; if ( (shiftby %= len) == 0 ) return s;
migf1 Δημοσ. 13 Φεβρουαρίου 2012 Μέλος Δημοσ. 13 Φεβρουαρίου 2012 Πριν από το... > if ( !s || shiftby < 0 || len < 1 ) return s; εννοείς; EDIT1: Τώρα έπιασα τι εννοείς! Να μην μπαίνει καν στη διαδικασία όταν δοθεί μηδενική μετατόπιση. Ναι είναι πολύ σωστή παρατήρηση, thanks! EDIT2: @nilos_gr: Τα έβαλα όλα σε μια συνθήκη (τα παλιά και την παρατήρησή σου)... διόρθωσα και τον κώδικα στον 1ο ποστ, thanks!
παπι Δημοσ. 13 Φεβρουαρίου 2012 Δημοσ. 13 Φεβρουαρίου 2012 Μια βελτιωση. αν shiftby% len > len / 2 τοτε κανεις right shift με shiftby shiftbyR = len - shiftbyL % len
migf1 Δημοσ. 13 Φεβρουαρίου 2012 Μέλος Δημοσ. 13 Φεβρουαρίου 2012 Μια βελτιωση. αν shiftby% len > len / 2 τοτε κανεις right shift με shiftby shiftbyR = len - shiftbyL % len Δεν το έχω "πιάσει" ακόμα τι κάνει αυτό, αλλά πρέπει να φύγω. Θα το δω μόλις πάω σπίτι (εξήγησέ το αν θες στο μεταξύ ). Thanks!
παπι Δημοσ. 13 Φεβρουαρίου 2012 Δημοσ. 13 Φεβρουαρίου 2012 πχ 1 2 3 4 5 6 left shift(4) 5 6 1 2 3 4 right shft(2) 5 6 1 2 3 4
Directx Δημοσ. 13 Φεβρουαρίου 2012 Δημοσ. 13 Φεβρουαρίου 2012 Επειδή δεν μου κάθεται πολύ καλά λόγω των malloc() μικρών ποσοτήτων, αλλά δεν μου έρχεται τώρα κάτι καλύτερο στο μυαλό (βασικά κάτι ταχύτερο, δεδομένου πως το c-string μπορεί να είναι πολύ μεγάλο), υπάρχει κάποια καλύτερη υλοποίηση κυκλικής μετατόπισης χαρακτήρων προς τα αριστερά ενός c-string από την παρακάτω; > char *s_shift_left( char *s, int shiftby, const int len ) { char *temp = NULL; /* if ( !s || shiftby < 0 || len < 1 ) return s; if ( shiftby > len-1 ) shiftby %= len; */ if ( !s || shiftby < 1 || len < 2 || (shiftby %= len) == 0 ) return s; if ( NULL == (temp = malloc( shiftby * sizeof(char) )) ) return s; memcpy( temp, s, shiftby * sizeof(char) ); memmove( s, &s[ shiftby ], (len-shiftby) * sizeof(char) ); memcpy( &s[ len-shiftby ], temp, shiftby * sizeof(char) ); free( temp ); return s; } Παραδείγματα: > char *s = "abcde"; s_shift_left( s, 1, strlen(s) ); // δίνει: "bcdea" > char *s = "abcde"; s_shift_left( s, 2, strlen(s) ); // δίνει: "cdeab" > char *s = "abcde"; s_shift_left( s, 5, strlen(s) ); // δίνει: "abcde" > char *s = "abcde"; s_shift_left( s, -1, ... ); // δίνει: "abcde" > char *s = "abcde"; s_shift_left( s, 25600, 0); // δίνει: "abcde" EDIT: Βελτίωση της αρχικής συνθήκης, κατόπιν εύστοχης παρατήρησης του φίλου nilos_gr! Σε σχόλια ο παλιός κώδικας. (τελικά το αφήνουμε με το malloc() ως η ταχύτερη δυνατή υλοποίηση; ) Πριν αρκετά χρόνια είχα ασχοληθεί με αυτό και για τις δυο κατευθύνσεις καθώς μου άρεσε ως εφέ (scroll κατά 1 χαρακτήρα είτε <-c είτε c->) εδώ, το καταθέτω μήπως φανεί χρήσιμο.
migf1 Δημοσ. 13 Φεβρουαρίου 2012 Μέλος Δημοσ. 13 Φεβρουαρίου 2012 πχ 1 2 3 4 5 6 left shift(4) 5 6 1 2 3 4 right shft(2) 5 6 1 2 3 4 Έξυπνο και χρήσιμο Έχω όμως την εντύπωση πως τη συγκεκριμένη υλοποίηση του 1ου ποστ δεν τη βοηθάει σε ταχύτητα, επειδή κάνουμε απευθείας indexing στην αρχή και στο τέλος του c-string (με s[ shiftby ] και s[ len-shiftby ], αντίστοιχα). Άρα δεν μας δίνει κάποιο κέρδος να το εξετάζουμε ξεχωριστά για το κάθε μισό του, αφού έτσι κι αλλιώς το ίδιο κομμάτι θα πρέπει να μετακινηθεί με memmove()....έτσι δεν είναι; Πριν αρκετά χρόνια είχα ασχοληθεί με αυτό και για τις δυο κατευθύνσεις καθώς μου άρεσε ως εφέ (scroll κατά 1 χαρακτήρα είτε <-c είτε c->) εδώ, το καταθέτω μήπως φανεί χρήσιμο. Όταν πρόκειται για 1 μόνο χαρακτήρα, είναι πολύ εύκολο... είναι αυτό που δείχνεις φίλε DirectX. Αλλά πρέπει να το διορθώσεις ώστε να μετράς το strlen() 1 μόνο φορά, αντί για 2 ή 3 που το μετράει η ρουτίνα που παραθέτεις. Δηλαδή να σώσεις αρχικά σε μια τοπική μεταβλητή το strlen( pszString )... π.χ. len = strlen( pszString )... και να χρησιμοποιείς αυτήν στη συνέχεια. Μπορείς να αντικαταστήσεις επίσης την strcpy() με την memcpy() που εκτελείται πολύ ταχύτερα
Directx Δημοσ. 13 Φεβρουαρίου 2012 Δημοσ. 13 Φεβρουαρίου 2012 [..]Όταν πρόκειται για 1 μόνο χαρακτήρα, είναι πολύ εύκολο... είναι αυτό που δείχνεις φίλε DirectX.[..] Αλλά πρέπει να το διορθώσεις ώστε να μετράς το strlen() 1 μόνο φορά, αντί για 2 ή 3 που το μετράει η ρουτίνα που παραθέτεις. Δηλαδή να σώσεις αρχικά σε μια τοπική μεταβλητή το strlen( pszString )... π.χ. len = strlen( pszString )... και να χρησιμοποιείς αυτήν στη συνέχεια. Μπορείς να αντικαταστήσεις επίσης την strcpy() με την memcpy() που εκτελείται πολύ ταχύτερα Δεν πρόκειται να το αλλάξω, τα έχουμε πει αυτά παλαιότερα, ακολουθώ διαφορετική φιλοσοφία φίλε migf1
migf1 Δημοσ. 13 Φεβρουαρίου 2012 Μέλος Δημοσ. 13 Φεβρουαρίου 2012 Δεν πρόκειται να το αλλάξω, τα έχουμε πει αυτά παλαιότερα, ακολουθώ διαφορετική φιλοσοφία φίλε migf1 Άμα σου πως ότι δε θυμάμαι
Directx Δημοσ. 13 Φεβρουαρίου 2012 Δημοσ. 13 Φεβρουαρίου 2012 Άμα σου πως ότι δε θυμάμαι Μέσο pm πριν καιρό, anyway δεν πειράζει
migf1 Δημοσ. 13 Φεβρουαρίου 2012 Μέλος Δημοσ. 13 Φεβρουαρίου 2012 Μέσο pm πριν καιρό, anyway δεν πειράζει Αααααα... ναι, θυμήθηκα
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα