2009-03-04 19 views

Respuesta

29

bien, sólo golpeó un poco de código para programar su método contra esta:

int count = 0; 
for (int i = 0; i < s.Length; i++) 
{ 
    if (char.IsUpper(s[i])) count++; 
} 

El resultado:

saluda: 19737 garrapatas

minas: 118 garrapatas

diferencia bastante grande! A veces, la forma más directa es la más eficiente.

Editar

Solo por curiosidad, esto:

int count = s.Count(c => char.IsUpper(c)); 

está en el puesto en alrededor de 2.500 garrapatas. Entonces, para un trazador de líneas "Linqy" es bastante rápido.

+1

+1 buena solución de la vieja escuela :) –

+0

D'oh! Pipped en la publicación, casi exactamente la misma solución. Bien hecho Matt, malditos dedos estúpidos y lentos. . . –

+0

Por cierto, +1 amigo, lo ganaste :) –

3

Sólo estás contando ASCII estándar y no ADE etc.

¿Qué tal

CommentText.ToCharArray().Where(c => Char.IsUpper(c)).Count() 
+0

gracias por eso - Estaba buscando c.Upper en intellisense - no pensé en el otro. – peterorum

+0

No lo olvide: Esto cuenta el número de letras mayúsculas independientemente del número de palabras. – PeterCo

3

Sin ni siquiera las pruebas diría

int count = 0; 
foreach (char c in commentText) 
{ 
    if (Char.IsUpper(c)) 
     count++; 
} 

es más rápido, ahora fuera de probarlo.

+0

Sí, eso está a la par (o quizás algunos tics más rápido) que mi ciclo "for". –

+0

No me molesté en probarlo, ya que Matt Hamilton fue lo suficientemente considerado como para hacer esto por mí :) –

6

Primero, no hay ninguna razón por la que deba llamar al ToCharArray() ya que, suponiendo que CommentText es una cadena, ya es un IEnumerable<char>. En segundo lugar, probablemente debería llamar al char.IsUpper en lugar de asumir que solo está tratando con valores ASCII. El código realmente debe ser similar,

CommentText.Count(char.IsUpper) 

En tercer lugar, si usted está preocupado acerca de la velocidad que no hay mucho que puede vencer a la edad de bucle,

int count = 0; 
for (int i = 0; i < CommentText.Length; i++) 
    if (char.IsUpper(CommentText[i]) count++; 

En general, llamar a cualquier método va ser más lento que escribir el código, pero este tipo de optimización solo debe realizarse si está absolutamente seguro de que este es el cuello de botella en su código.

+0

Amigo, ¿debería "haber mucho" ser "no hay mucho"? –

+0

Doh, sí. Fijo. – chuckj

+0

Gracias por su respuesta. Muy sucinto código linq. – peterorum

2

Lo que está haciendo con ese código es crear una colección con los caracteres, luego crear una nueva colección que contenga solo los caracteres en mayúsculas, luego recorra esa colección solo para descubrir cuántos hay.

Esto se obtienen mejores resultados (pero todavía no es tan bueno como un bucle sin formato), ya que no crea las colecciones intermedias:

CommentText.Count(c => Char.IsUpper(c)) 

Editar: Se ha eliminado la llamada ToCharArray también, como Matt sugirió.

+0

+1 para mover el predicado al Conteo. Quítese también el ToCharArray y se acelera de forma espectacular. –

+0

Buen punto. Hice algo similar antes y luego se necesitó ToCharArray, pero no en este caso. :) – Guffa

2

Tengo este

Regex x = new Regex("[A-Z]{1}", 
    RegexOptions.Compiled | RegexOptions.CultureInvariant); 
int c = x.Matches(s).Count; 

pero no sé si es particularmente rápida. No va a caracteres especiales, ya sea, yo -Supongo

EDIT:

Comparativa rápida de la respuesta de esta pregunta. Depurar en vshost, 10000 iteraciones con la cadena:
aBcDeFGHi1287jKK6437628asghwHllmTbynerA

  • La respuesta: 20-30 ms
  • La solución de expresiones regulares: 140-170 ms
+0

Gracias por la comparación, me pregunté cómo se podría comparar una expresión regular. – peterorum

+0

Puede mezclar esto en una sola línea: 'Regex.Matches (s," [A-Z] {1} ", RegexOptions.Compiled | RegexOptions.CultureInvariant) .Count;' –

Cuestiones relacionadas