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

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

Δημοσ. (επεξεργασμένο)

Επειδή δεν μου κάθεται πολύ καλά λόγω των 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() ως η ταχύτερη δυνατή υλοποίηση; )

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

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;

Δημοσ.

Πριν από το...

>
if ( !s || shiftby < 0 || len < 1 )
               return s;

εννοείς;

 

EDIT1:

 

Τώρα έπιασα τι εννοείς! Να μην μπαίνει καν στη διαδικασία όταν δοθεί μηδενική μετατόπιση. Ναι είναι πολύ σωστή παρατήρηση, thanks!

 

EDIT2:

 

@nilos_gr: Τα έβαλα όλα σε μια συνθήκη (τα παλιά και την παρατήρησή σου)... διόρθωσα και τον κώδικα στον 1ο ποστ, thanks!

Δημοσ.

Μια βελτιωση.

αν

shiftby% len > len / 2

τοτε κανεις right shift με shiftby

shiftbyR = len - shiftbyL % len

Δεν το έχω "πιάσει" ακόμα τι κάνει αυτό, αλλά πρέπει να φύγω. Θα το δω μόλις πάω σπίτι (εξήγησέ το αν θες στο μεταξύ ). Thanks!

Δημοσ.

Επειδή δεν μου κάθεται πολύ καλά λόγω των 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->) εδώ, το καταθέτω μήπως φανεί χρήσιμο.

Δημοσ.

πχ 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() που εκτελείται πολύ ταχύτερα ;)

Δημοσ.
[..]

Όταν πρόκειται για 1 μόνο χαρακτήρα, είναι πολύ εύκολο... είναι αυτό που δείχνεις φίλε DirectX.[..]

 

 

Αλλά πρέπει να το διορθώσεις ώστε να μετράς το strlen() 1 μόνο φορά, αντί για 2 ή 3 που το μετράει η ρουτίνα που παραθέτεις. Δηλαδή να σώσεις αρχικά σε μια τοπική μεταβλητή το strlen( pszString )... π.χ. len = strlen( pszString )... και να χρησιμοποιείς αυτήν στη συνέχεια. Μπορείς να αντικαταστήσεις επίσης την strcpy() με την memcpy() που εκτελείται πολύ ταχύτερα ;)

 

Δεν πρόκειται να το αλλάξω, τα έχουμε πει αυτά παλαιότερα, ακολουθώ διαφορετική φιλοσοφία φίλε migf1 ;)

 

Δημοσ.

Δεν πρόκειται να το αλλάξω, τα έχουμε πει αυτά παλαιότερα, ακολουθώ διαφορετική φιλοσοφία φίλε migf1 ;)

 

 

Άμα σου πως ότι δε θυμάμαι :huh:

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

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

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

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

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

Σύνδεση

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

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