sábado, 11 de junio de 2022

Curso Avanzado de C#. Manipulación de cadenas II

Clases String adicionales 

La clase String es intuitiva y fácil de usar. Podemos utilizar sus métodos para examinar fácilmente las cadenas, eliminar secciones, recortar el inicio o el final de una cadena y extraer subcadenas. Sin embargo, la forma inusual en que se introducen cadenas en nuestro programa, las hace ineficaces para algunos propósitos. La figura muestra el programa de ejemplo de permutaciones.

Clases String adicionales


Este programa muestra una cadena grande que contiene todas las permutaciones de un conjunto de letras entre la A y la H. Hay 8 letras y (5040 permutaciones de esas ocho letras) por lo que el resultado es 5040 cadenas concatenadas. Para empeorar las cosas, el programa crea cada permutación con un carácter cada vez, por lo que cada permutación requiere la construcción de ocho cadenas más pequeñas. Esto significa que el programa construye 8 × 5040 = 40.320 cadenas en total, cada una de las cuales debe ser ingresada. Como resultado, el programa es bastante lento, tardando aproximadamente 23 segundos en producir estas 5.040 permutaciones utilizando la concatenación de cadenas. Para casos especiales como este, cuando la clase String es particularmente ineficiente, un programa puede obtener un mejor rendimiento utilizando las clases de procesamiento de cadenas especializadas: 


StringBuilder 

StringWriter 

StringReader 

El programa tomó solo 0.05 segundos para construir las permutaciones cuando utilizamos StringBuilder en lugar de concatenaciones de String. Cada una de estas clases de procesamiento de cadenas se describe en las siguientes secciones. 

StringBuilder 

La clase StringBuilder representa una cadena mutable no internada. Almacena datos de caracteres en una matriz y puede agregar, eliminar, reemplazar y agregar caracteres sin crear un nuevo objeto String o usar el grupo interno. Normalmente, un programa usa un StringBuilder para construir una cadena en una larga serie de pasos y luego llama al método ToString de StringBuilder para convertir el resultado en una cadena normal. Por ejemplo, el siguiente código utiliza StringBuilder para construir una cadena que contiene una serie de nombres de empleados en líneas separadas:

String[] NombresEmpleados =

{

      "Abel",

      "Bartolo",

      "Carlos",

      "David",

};

StringBuilder allNames = New StringBuilder();

foreach (string name in NombresEmpleados)

{

      allNames.Append("[" + name + "]" + Environment.NewLine);

}

txtEmpleados.Text = allNames.ToString();

El código comienza definiendo una matriz de nombres de empleados. Luego crea un StringBuilder y recorre los nombres en la matriz NombresEmpleados. Para cada nombre, el código llama al método Append de StringBuilder para agregar el nombre entre corchetes a la cadena. Una vez que ha procesado todos los nombres, el código llama al método ToString de StringBuilder para convertirlo en un String normal y muestra el resultado en la caja de texto txtEmpleados

La Tabla describe las propiedades más útiles de la clase StringBuilder.

 

Propiedad

Descripción

Capacity

Obtiene o establece el número de caracteres que puede contener StringBuilder. Si la cantidad de texto almacenado en StringBuilder excede esta cantidad, el objeto asigna más espacio. Si sabe que StringBuilder debe contener al menos un cierto número de caracteres, podemos utilizar esta propiedad para hacer que el objeto se preasigne

memoria en lugar de asignar memoria de forma incremental. Algunas versiones sobrecargadas del constructor de la clase  permiten especificar una capacidad inicial.

Length

Obtiene o establece el número actual de caracteres almacenados en StringBuilder. Si establecemos este valor a un menor valor que la longitud actual, el texto en StringBuilder se trunca.

El indexador de StringBuilder devuelve los caracteres almacenados en el objeto. Un programa puede usar el indexador para obtener y establecer valores de caracteres. Por ejemplo, la declaración allNames [10] = 'X' establece el carácter número 10 en X. 

La tabla describe los métodos más útiles de la clase StringBuilder.

 

Método

Descripción

Append

Añade una representación de cadena de un objeto al final del texto de StringBuilder

AppendFormat

Formatea una serie de objetos y agrega el resultado al final del texto de StringBuilder

EnsureCapacity

Garantiza que StringBuilder tenga al menos una capacidad determinada

Insert

Inserta una representación de cadena de un objeto en una posición dada en el texto de StringBuilder

Remove

Elimina un rango de caracteres del texto de StringBuilder

Replace

Reemplaza todas las instancias de un carácter o cadena con un nuevo carácter o cadena

ToString

Devuelve una representación de cadena normal del texto de StringBuilder

 

La clase StringBuilder agrega algo de sobrecarga a un programa y, a veces, hace que el código sea más difícil de leer, por lo que generalmente debemos usarlo solo si realizamos una gran cantidad de operaciones de cadena. En un conjunto de pruebas, la concatenación de cadenas simple fue más rápida que la creación y el uso de StringBuilder para menos de aproximadamente siete concatenaciones.

También hay que tener en cuenta en cuenta que los tiempos involucrados para algunas operaciones de cadena son pequeños. Pero utilizar StringBuilder para concatenar 10 cadenas puede ser un poco más rápido que realizar 10 concatenaciones simples de cadena, pero la cantidad total de tiempo ahorrado se mide en milisegundos. A menos que el programa repita esa operación muchas veces o haga concatenaciones mucho más largas, podemos sacrificar algunos milisegundos para que el código sea más fácil de entender. 

StringWriter 

La clase StringWriter proporciona una interfaz que facilita en algunos casos la creación de una cadena en un StringBuilder subyacente. La clase StringWriter proporciona métodos que facilitan la escritura secuencial de valores en una cadena. La tabla  describe los métodos más útiles de StringWriter. 

 

Método

Descripción

Flush

Vacía los datos almacenados en búfer en el StringWriter subyacente

ToString

Devuelve el contenido actual del objeto como una cadena

Write

Añade un elemento a los datos de la cadena. Las versiones sobrecargadas agregan char, string, int, double y otros muchos tipos de datos.

WriteAsync

Anexa de forma asíncrona un char,string o una matriz de caracteres al final de los datos de la cadena

WriteLine

Agrega un elemento a los datos de la cadena como lo hace Write y luego agrega una nueva línea

 

StringWriter puede ser útil cuando solo deseamos agregar valores a una cadena. StringWriter también implementa una interfaz TextWriter, lo que puede ser útil cuando otras clases requieren un TextWriter para producir una salida y deseamos almacenar esa salida en una cadena. Por ejemplo, el método Serialize de la clase XmlSerializer envía la salida a un TextWriter. Si queremos serializar en una cadena, podemos enviar la salida a StringWriter y luego usar el método ToString de StringWriter para obtener el resultado. Si necesita manipular los datos de la cadena subyacente de otras formas, como eliminar o reemplazar caracteres, StringBuilder proporciona más flexibilidad. 

StringReader 

La clase StringReader proporciona una implementación TextReader que lee fragmentos de datos tomados de un StringBuilder subyacente. Proporciona métodos que facilitan la lectura secuencial de fragmentos de texto de una cadena. La tabla  describe los métodos más útiles de StringReader.

 

Método

Descripción

Peek

Devuelve el siguiente carácter en los datos pero no avanza al carácter

Read

Devuelve el siguiente carácter de los datos y avanza al siguiente carácter. Una versión sobrecargada puede leer un bloque de caracteres

ReadAsync

Lee de forma asíncrona caracteres de StringReader en un búfer

ReadBlock

Lee hasta un número máximo de caracteres de StringReader en un búfer que comienza en un índice especificado

ReadBlockAsync

Lee asincrónicamente hasta un número máximo de carácteres de StringReader en un búfer que comienza en un índice especificado.

ReadLine

Lee carácteres de StringReader hasta que encuentra el final de línea

ReadLineAsync

Lee de forma asíncrona los caracteres de StringReader hasta que encuentra el fin de la línea

ReadToEnd

Devuelve el texto restante de StringReader como una cadena

ReadToEndAsync

Devuelve de forma asíncrona el texto restante de StringReader como una cadena

 

La clase StringReader proporciona acceso a los datos de StringBuilder a un nivel relativamente bajo. A menudo, un programa usa un StringReader solo porque necesita pasar información a un método predefinido que requiere un StringReader o TextReader como parámetro. 

Veamos un ejemplo: Usando StringBuilder 

Usando solo StringBuilders (sin Strings), escribir un programa que muestre todas las subsecuencias iniciales de las letras del alfabeto A, AB, ABC, y así sucesivamente en un TextBox, como se muestra en la figura 

StringBuilder

Private void Form1_Load(Object sender, EventArgs e)

{

      // Genera un StringBuilder sosteniendo los ABC

      StringBuilder letters =

      New StringBuilder("ABCDEFGHIJKLMNOPQRSTUVWXYZ");

      // Éste contiene la siguiente línea de letras.

      StringBuilder line = New StringBuilder();

      // Crea el resultado StringBuilder.

      StringBuilder result = New StringBuilder();

      // Recorre las letras.

      For (int i = 0; i < 26; i++)

      {

            // Agregua la siguiente letra a la línea.

            line.Append(letters[i]);

            //Agrega una línea al resultado.

            result.AppendLine(line.ToString());

      }

      // Muestra el resultado.

      stringBuilderTextBox.Text = result.ToString();

      stringBuilderTextBox.Select(0, 0);

}

El código construye un StringBuilder que contiene las letras del alfabeto. Hace un segundo StringBuilder para mantener una línea de salida y un tercero para mantener el resultado final. A continuación, el código recorre los números del 0 al 25. Para cada valor de i, el código agrega el i-ésimo carácter en letras al valor en línea. Luego agrega el nuevo valor de línea al resultado, siguiéndolo con una nueva línea. Cuando el código termina su ciclo, muestra el resultado. En este ejemplo, no está claro si usar StringBuilder es más rápido que usar concatenaciones de cadenas simples. En una prueba que ejecutó este código y un código similar que realizó concatenaciones de cadenas 100.000 veces, la versión de StringBuilder tomó aproximadamente el 54 por ciento de tiempo, por lo que hay un ahorro de tiempo, pero el resultado para una sola ejecución es insignificante.


No hay comentarios:

Publicar un comentario