2012-06-17 35 views
5

¿Cómo puedo contar el número de ocurrencias en una cadena C de /?¿Cómo puedo contar el número de apariciones del carácter '/' en una cadena C?

Puedo hacer esto:

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

Pero esto no es una manera elegante; alguna sugerencia sobre cómo mejorarlo?

+3

El suyo es lo suficientemente elegante IMO ... –

+1

La principal crítica podría ser la interfaz bastante especializada en comparación con 'int countChar (char const * str, char c)', que (a) promete no modificar la cadena que se pasa, y (b) se puede usar para contar asteriscos, espacios en blanco, etc., esencialmente sin pérdida de eficiencia. Puede escribir una función simple 'int countSlash (char const * str) {return countChar (str, '/'); } 'si realmente quieres la interfaz menos general. Hay una posibilidad decente de que el compilador optimice eso para usted si la habilitación, etc. está habilitada. –

+0

Elegancia, podría ser de muchas maneras diferentes. Puede ser el más corto, el más legible o el más fácil de entender. Y el más legible, también podría ser el más ilegible para otra persona. Por lo tanto, la 'Elegancia' es un pensamiento subjetivo. Tal vez deberías pedir la manera más EFICIENTE, en términos de velocidad. – ChinoCarloSedilla

Respuesta

5

strchr haría un lazo más pequeño:

ptr = str; 

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

debo añadir que no apoyo la brevedad por el bien de la brevedad, y siempre voy a optar por la expresiónmás clara, siendo iguales todas las demás cosas . Encuentro el lazo strchr más elegante, pero la implementación original en la pregunta es clara y vive dentro de una función, por lo que no prefiero una sobre la otra, siempre y cuando ambas pasen las pruebas unitarias.

+1

¡Es cierto, pero no hay una buena razón para escribir un código como ese en el siglo XXI! –

+1

@OliCharlesworth HA tal vez. No tengo ningún problema con este tipo de 1-line en C estándar, pero de nuevo los bucles de este tipo a menudo no terminan en mi propio código. – pb2q

+3

¿Cómo escribiría un codificador en el siglo 21 C el código, @OliCharlesworth? Soy un codificador de 20th Century C que todavía está trabajando; Lo que pb2q ha escrito me parece bien como el cuerpo de la función 'countSlash()'. –

2

El suyo es lo suficientemente bueno. Tal vez, esto se vería más bonito en cierta:

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

Esto también funciona:

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

¿Por qué no hay espacios? ¿Por qué el elenco? ¿Por qué no simplemente 'n + = (* s ++ == '/');'? –

+0

@JonathanLeffler: Sí, sería más fácil para el ojo;) - el elenco: porque la str [] es una matriz y no una cadena, y esta es C – slashmais

+1

@slashmais, estoy bastante seguro de que el reparto explícito es totalmente redundante. Ha pasado mucho tiempo desde que realicé una codificación real en C, pero, como recuerdo, al pasar una variable que hace referencia a una matriz, automáticamente se degrada a un puntero al primer elemento de dicha matriz. Por lo tanto, 'char str []' y 'char * str' deben ser completamente intercambiables para todos los efectos. –

2

interfaz genérica, enfoque obvio, tipos apropiados y expresiones puramente idiomáticas:

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 probablemente plantearía inquietudes con respecto a asignaciones y condicionales en la misma línea, pero creo que está bastante bien escondido ;-)

+0

+1 por la idea, me encantó – ron

+0

Podría estar equivocado, pero creo que tu loop invariante se puede simplificar hasta simplemente 'while (* s)'. Solo debería ser necesario comprobar que 's' no es un puntero' NULL' al comienzo de la ejecución. –

+0

@GregE .: tienes razón, es necesario verificar 'NULL' como máximo una vez aquí. Creo firmemente que el compilador es más inteligente que yo, por lo tanto, estoy confiando en el compilador para optimizar esto. Debería ser fácil ya que no estamos modificando 's' en ninguna parte de esta función. – Philip

Cuestiones relacionadas