2012-03-28 26 views
7

tengo esta cadena:la forma más eficiente de la cadena separada

"B82V16814133260"

lo que sería la forma más eficiente para obtener dos cadenas de ella:

parte izquierda de la secuencia: " B82V " parte derecha cadena:" 16814133260 "

La regla es la siguiente: tome todos los números del lado derecho y cree una cadena de ellos, luego tome el recordatorio y colóquelo en otra secuencia.

¡Esta es mi solución, pero es demasiado voluminosa! ¿Cómo hacerlo breve y eficiente?

 String leftString = ""; 
     String rightString=""; 

     foreach (char A in textBox13.Text.Reverse()) 
     { 
      if (Char.IsNumber(A)) 
      { 
       rightString += A; 
      } 
      else 
      { 
       break; 
      } 
     } 

     char[] arr = rightString.ToArray(); 
     Array.Reverse(arr); 

     rightString=new string(arr); 
     leftString = textBox13.Text.Replace(rightString, ""); 
+2

¿Qué quieres decir con "eficiente"? Eficiente en la memoria o en el rendimiento? – Tigran

+0

Por curiosidad, ¿por qué su solución es "demasiado voluminosa"? Parece ser una buena parte de una función para mí. – Bob2Chiv

+2

Voy a publicar el Regex correspondiente, pero lo juro por Dios si alguien más lo publica primero ... – mowwwalker

Respuesta

14

Esto produce lo que estás esperando:

var given = "B82V16814133260"; 
var first = given.TrimEnd("".ToCharArray()); 
var rest = given.Substring(first.Length); 

Console.Write("{0} -> {1} -- {2}", given, first, rest); 
// B82V16814133260 -> B82V -- 16814133260 
+0

+1: Mientras teóricamente escaneaba la cadena hasta que 'ch < '0' || ch >' 9'' y luego dividir en el índice suena como el más rápido, tomaría una aplicación científica para diferenciar (tal vez). – Jon

+0

¡Guau, esto es como un dios! – Andrew

+3

Una solución elegante. No sabía sobre TrimEnd. – captncraig

4

Esto debe ser muy rápido:

int index = text.Length - 1; 
while (index >= 0 && Char.IsDigit(text[index])) 
{ 
    index--; 
} 
string left = text.Substring(0, index + 1); 
string right = text.Substring(index + 1); 
+0

Muy rápido en comparación con qué? –

+0

@AshBurlaczenko: no hay asignaciones innecesarias de 'string',' reversing' de la cadena y ninguna asignación 'array'. * Debería * ser más rápido. – Tigran

+0

En realidad, yo preferiría esta respuesta como una correcta, porque es más clara y * debería * ser más rápida que la más votada, aunque debería admitir que la más votada es definitivamente "más linda". – Tigran

1

me gusta LINQ.

var s = "B82V16814133260"; 
    var lastNonNumeric = s.Reverse().Where(x => !char.IsDigit(x)).FirstOrDefault(); 
    var index = s.LastIndexOf(lastNonNumeric); 
    var secondString = s.Substring(index + 1); 
    var firstString = s.Substring(0, index+1); 

Probablemente no sea la mejor solución ni la más robusta, pero funciona para su cadena de prueba.

+0

Revertir sería una pérdida de esfuerzo ya que no necesita mantener el resultado invertido. La última (ch => '0' <= ch && ch <= '9') sería más rápida. –

+0

Estoy de acuerdo. Todavía no es tan bueno como la solución de Austin, así que no me molestaré en editarlo. – captncraig

5

Bueno, la otra respuesta es probablemente mejor, pero me escribió esto de todos modos, por lo que he publicado:

Necesidades:

using System.Text.RegularExpressions; 

Código:

string str = "B82V16814133260"; 
string[] match = Regex.match(str, @"^([\d\w]+?\w)(\d+)$").Groups; 
string left = match[1]; 
string right = match[2]; 
+0

¡también es una solución muy buena! – Andrew

+1

@walkerneo solo un hecho divertido, ejecutar expresiones regulares para esto (Regex compilada también, lanzamiento de compilación) tomó 1605.3 segundos, o 856.4 veces más) Entonces, si la velocidad es 'eficiente', regex no es 'eficiente'. – payo

+0

@payo, bien, gracias, lo asumí. Sin embargo, si cambian sus requisitos, de modo que la cadena no termine en solo dígitos, esto será más fácil de modificar. No puedo decir si eso es posible en su situación, y por lo que sé, esas cadenas siempre estarán en el mismo formato, pero aún así, nunca se sabe. – mowwwalker

0
string Source = textBox13.Text; 

for (i = Source.Length - 1; i >=0; i--) 
{ 
     if (! Char.IsNumber(Source[i]) 
     break; 
} 

string leftString = Source.Left(i+1); 
string rightString = Source.Right(i+1,Source.Length-i-1); 
2

Leí "más eficiente" como "más rápido".

Escribí una prueba rápida con una cadena larga, ejecutando 10 millones de veces.

solución de Austin a utilizar TrimEnd corrieron en 4.649s

Mi solución corrió en 1.927 segundos

int j = given.Length - 1; 

    for (; j >= 0; j--) 
    { 
     char c = given[j]; 
     if (c < '0' || c > '9') 
     { 
     break; 
     } 
    } 

    var first = given.Substring(0, j + 1); 
    var rest = given.Substring(j + 1); 

Nota que mi construye no fuera de depuración (en la depuración, mi solución es más lento, pero eso es porque TrimEnd no se está ejecutando en bits de depuración). Entonces, si está ejecutando mi código en su aplicación y está construyendo depuración, será más lento.

+0

+1 para sincronizar el mío. –

Cuestiones relacionadas