2012-06-17 25 views
5

Come posso contare il numero di occorrenze in una stringa C di /?Come posso contare il numero di occorrenze del carattere '/' in una stringa C?

posso fare questo:

int countSlash(char str[]) 
{ 
    int count = 0, k = 0; 
    while (str[k] != '\0') 
    { 
      if (str[k] == '/') 
       count++; 
      k++; 
    } 
    return count; 
} 

Ma questo non è un modo elegante; qualche suggerimento su come migliorarlo?

+3

Il tuo è abbastanza elegante IMO ... –

+1

La critica principale potrebbe essere l'interfaccia piuttosto specializzata rispetto a 'int countChar (char const * str, char c)', che (a) promette di non modificare la stringa che viene passata, e (b) può essere usato per contare asterischi, spazi vuoti, ecc con essenzialmente nessuna perdita di efficienza. Puoi scrivere una semplice funzione 'int countSlash (char const * str) {return countChar (str, '/'); } 'se vuoi davvero un'interfaccia meno generale. C'è una buona possibilità che il compilatore ottimizzerà questo per te se l'inlining etc è abilitato. –

+0

Eleganza, potrebbe essere in molti modi diversi. Potrebbe essere il più breve, o il più leggibile, o il più facilmente comprensibile. E il più leggibile, potrebbe anche essere il più illeggibile per l'altra persona. Pertanto, l '"Eleganza" è un pensiero soggettivo. Forse dovresti chiedere il modo più EFFICIENTE, in termini di velocità. – ChinoCarloSedilla

risposta

5

strchr farebbe un ciclo più piccolo:

ptr = str; 

while ((ptr = strchr(ptr '/')) != NULL) 
    count++, ptr++; 

Vorrei aggiungere che io non approvo brevità per brevità, e sarò sempre optare per la più chiara espressione, tutte le altre cose sono uguali . Trovo il ciclo strchr più elegante, ma l'implementazione originale nella domanda è chiara e vive all'interno di una funzione, quindi non preferisco l'una sull'altra, fintanto che entrambe superano i test unitari.

+1

Vero, ma non c'è una buona ragione per scrivere un codice del genere nel 21 ° secolo! –

+1

@OliCharlesworth HA forse così. Non ho problemi con questo tipo di 1-liner in standard C, ma poi i loop di questo tipo spesso non finiscono nel mio codice. – pb2q

+3

In che modo un 21st Century C Coder scrive il codice, @OliCharlesworth? Sono un codificatore del XX secolo che sta ancora lavorando; ciò che mi ha scritto pb2q mi sembra OK come corpo della funzione 'countSlash()'. –

2

Il tuo è abbastanza buono. Forse, questo apparirebbe più bello ad alcuni:

int countSlash(char * str) 
{ 
    int count = 0; 
    for (; *str != 0; ++str) 
    { 
     if (*str == '/') 
      count++; 
    } 
    return count; 
} 
0

Questo funzionerà anche:

int count=0; 
char *s=str; 
while (*s) count += (*s++ == '/'); 
+3

Perché non ci sono spazi? Perché il cast? Perché non solo 'n + = (* s ++ == '/');'? –

+0

@JonathanLeffler: Sì, sarebbe più facile per gli occhi;) - il cast: perché lo str [] è un array e non una stringa, e questo è C – slashmais

+1

@slashmais, sono abbastanza sicuro che il cast esplicito è totalmente ridondante. È passato molto tempo da quando ho fatto un vero codice in C, ma, come ricordo, quando si passa una variabile che fa riferimento a un array, esso viene automaticamente abbassato di livello in un puntatore al primo elemento di tale array. Quindi 'char str []' e 'char * str' dovrebbero essere completamente intercambiabili a tutti gli effetti. –

2

Interfaccia generica, approccio più ovvio, i tipi appropriati e le espressioni puramente idiomatiche:

size_t str_count_char(const char *s, int c) 
{ 
    size_t count = 0; 

    while (s && *s) 
     if (*s++ == c) 
      ++count; 

    return count; 
} 

Oli Charlesworth probabilmente solleverebbe preoccupazioni riguardo a incarichi e condizionali sulla stessa linea, ma penso che sia abbastanza ben nascosto ;-)

+0

+1 per l'idea, mi è piaciuto – ron

+0

Potrei sbagliarmi, ma penso che il tuo ciclo invariante può essere semplificato fino a 'while (* s)'. Dovrebbe essere solo necessario controllare che 's' non sia un puntatore' NULL' proprio all'inizio dell'esecuzione. –

+0

@GregE .: Hai ragione, il controllo di 'NULL' è richiesto al massimo una volta qui. Credo fermamente che il compilatore sia più intelligente di me, quindi mi affido al compilatore per ottimizzarlo. Dovrebbe essere facile dato che non stiamo modificando 's' da nessuna parte in questa funzione. – Philip

Problemi correlati