2011-06-01 10 views
20

Mi primera idea es hacer la aplicación simplemente:¿Cuál es la forma más rápida de verificar si la cadena tiene una letra mayúscula en C#?

bool hasUpperCase (string str) { 
    if(string.IsNullOrEmpty(str)) 
     return false; 
    for (int i = 0; i < str.Length; i++) { 
     if (char.IsUpper (str[i])) 
      return true;      
    } 
    return false; 
} 

pero tal vez hay otra manera más rápida de hacer eso?

+3

Lo consideraría "lo suficientemente rápido". – BoltClock

+1

Creo que es un buen enfoque, podría usar LINQ para hacer el trabajo del bucle for, pero el código generado sería equivalente. También podría probar que la cadena original no es igual a la cadena convertida a minúscula, pero espero que sea menos eficiente ya que siempre requerirá una poligonal completa de la cadena. – Clayton

+0

Puede haber algunos problemas de rendimiento con el uso de LINQ en lugar de un for-loop – VisualBean

Respuesta

39

Se podría reducir eso a

bool HasUpperCase (string str) { 
    return !string.IsNullOrEmpty(str) && str.Any(c => char.IsUpper(c)); 
} 

usando LINQ.

+1

e reducir nuevamente a: return! String.IsNullOrEmpty (contraseña) && password.Any (char.IsUpper); –

+0

entonces, si tiene la cadena "12345", entonces HasUpperCase todavía devolvería verdadero ... existe la necesidad de verificar AZ – Allie

+0

@SmartPCInformatica Su comentario parece ser incorrecto [Ejemplo de DotNetFiddle] (https://dotnetfiddle.net/ shsyaG). –

9

Cheating from here:

bool hasUpperCase (string str) { 
if(string.IsNullOrEmpty(str)) 
    return false; 

    return str != str.ToLower(); 
} 
+0

Necesita una verificación nula. – BoltClock

+0

¿Qué tan eficiente es esto? Necesita hacer una copia de la cadena solo para hacer la comparación. – Yuck

+0

@BoltClock: ¡Gracias! –

3
bool hasUpperCase(string str) { 
    if (string.IsNullOrEmpty(str)) 
     return false; 
    return Regex.IsMatch(str, "[A-Z]"); 
} 

exención de responsabilidad: No soy experto pero Regex He probado esto con las cuerdas Testing, testinG, and tesTing, la que todos evaluarse como VERDADERO. Sin embargo, también se evaluó como verdadero con la cadena TESTING, que puede o no puede querer.

2

El código me parece bien, ya que pide rendimiento, puede reducir el bucle for de O (n) a O (n/2 + ~ 1) agregando la verificación condicional desde el reverso.

De lo contrario, puede verificar dos elementos subsecuentes e incrementar el i en 2. Obviamente, debe verificar istr.Length para el segundo argumento.

bool hasUpperCase (string str) { 
if(string.IsNullOrEmpty(str)) 
    return false; 
for (int i = 0; i < str.Length; i= i + 2) { 
    if (char.IsUpper (str[i])) 
     return true;      

    if ((i + 1) < str.Length && char.IsUpper (str[i+1])) 
     return true;      
} 
return false; 

}

en mi humilde opinión, este consejo puede ayudar a responder a la entrevista algoritmo, no es mucho el rendimiento.

5

bien - ¡hora de la nueva verdad!

Esta fue una prueba para cualquier carácter en mayúscula de una cadena.

Se garantizó que la cadena no tenía caracteres en mayúscula dentro de los primeros 60K de caracteres. (Creé la cadena de random.org)

Evité la optimización de sustitución de cadenas en el compilador aleatorizando qué cadena de caracteres de 64K se pasó a la función de prueba.

Todos los tiempos eran muy estrictos con respecto a la prueba real, y no incluían el tiempo de llamadas a funciones.

Corrí la prueba una vez, 10 veces, y de nuevo por 10.000 veces y un promedio de cada conjunto de las temporizaciones para cada prueba.

que corrió la prueba en una de 64 bits de Windows 7 con i3-2100 CPU @ 3.1 Ghz

caso de prueba 1:

static bool testCaseOne(string str, out double ms) 
    { 
     bool result = false; 
     DateTime start = DateTime.Now; 

     result = !string.IsNullOrEmpty(str) && str.Any(c => char.IsUpper(c)); 
     ms = (DateTime.Now - start).TotalMilliseconds; 
     return result; 
    } 

Resultando tiempo promedio:

  1. 1 X = 3,000 ms
  2. 10 x = 0.860 ms
  3. 10,000 x = 0.821 ms

caso de prueba 2:

static bool testCaseTwo(string str, out double ms) 
    { 
     bool result = false; 
     DateTime start = DateTime.Now; 

     if (string.IsNullOrEmpty(str)) 
     { 
      ms = 0; 
      return false; 
     } 
     result = Regex.IsMatch(str, "[A-Z]"); 

     ms = (DateTime.Now - start).TotalMilliseconds; 

     return result; 
    } 

resultantes tiempo promedio:

  1. 1 x = 2.000 ms
  2. 10 x = 1.597 ms
  3. 10.000 x = 1.603 ms

caso de prueba 3:

static bool testCaseThree(string str, out double ms) 
    { 
     bool result = false; 
     DateTime start = DateTime.Now; 

     if (string.IsNullOrEmpty(str)) 
     { 
      ms = 0; 
      return false; 
     } 
     for (int i = 0; i < str.Length; i++) 
     { 
      if (char.IsUpper(str[i])) 
      { 
       result = true; 
       break; 
      } 
     } 
     ms = (DateTime.Now - start).TotalMilliseconds; 
     return result; 
    } 

resultante tiempo promedio:

  1. 1 x = 1.000 ms
  2. 10 x = 0,357 ms
  3. 10.000 x = 0,298 ms

Prueba Caso 4:

static bool testCaseFour(string str, out double ms) 
    { 
     bool result = false; 
     DateTime start = DateTime.Now; 

     if (string.IsNullOrEmpty(str)) 
     { 
      ms = 0; 
      return false; 
     } 
     for (int i = 0; i < str.Length; i++) 
     { 

      if (str[i] > 64 && str[i] < 91) 
      { 
       result = true; 
       break; 
      } 
     } 
     ms = (DateTime.Now - start).TotalMilliseconds; 
     return result; 
    } 

} 

resultante tiempo promedio:

  1. 1 x = 0,000 ms
  2. 10 x = 0,137 ms
  3. 10.000 x = 0,184 ms

interesante.

espero que este statisfies Sr. RK;)

+0

¿Te das cuenta de que los casos 1 y 4 son idénticos pero tienen diferentes resultados de tiempo? –

+0

debe haber copiado el código incorrecto, eso fue hace mucho tiempo, no recuerdo lo que hice para el caso 4 ... ¡Lo siento! –

+1

Ok, dado que el Sr. Koritnik (sollozo) me golpeó tanto, actualicé mi respuesta arriba ...;) –

0
public static string Upper_To_Lower(string text) 
    { 
     if (Char.IsUpper(text[0]) == true) { text = text.Replace(text[0], char.ToLower(text[0])); return text; } 

     return text; 
    } 

    public static string Lower_To_Upper(string text) 
    { 
     if (Char.IsLower(text[0]) == true) { text = text.Replace(text[0], char.ToUpper(text[0])); return text; } 

     return text; 
    } 

Aquí hice 2 métodos sencillos que comprueban la primera letra de cualquier cadena y convertirla de un extremo a otro y virse verca .... esperar que Te ayudará.

Cuestiones relacionadas