ESTRUCTURAS DE DATOS VIII.1

I N D I C E D E C O N T E N I D O S CAPI TULO VII I VIII. ESTRUCTURAS DE DATOS ...........................................................243 VIII.

2 downloads 130 Views 855KB Size

Story Transcript

I N D I C E

D E

C O N T E N I D O S

CAPI TULO VII I VIII. ESTRUCTURAS DE DATOS ...........................................................243 VIII.1.

Arreglos (Array) ..................................................................243

VIII.1.i.

Definición.............................................................................244

VIII.1.ii. Arreglos estáticos y dinámicos .........................................245 VIII.1.iii. Declaración de arreglos estáticos.....................................245 VIII.1.iv. Option Base .........................................................................246 VIII.1.v. Trabajar con elementos del vector...................................247 VIII.1.vi. Funciones de VB: LBound y UBound.................................248 VIII.1.vii. Arreglos dinámicos .............................................................249 VIII.1.viii.

Funciones que devuelven arreglos.............................252

VIII.1.ix. Funciones Join, Split y Filter .............................................253 VIII.1.ix.1.

Función Join ..................................................................254

VIII.1.ix.2.

Función Split .................................................................254

VIII.1.ix.3.

Función Filter ................................................................257

VIII.1.x. Valores máximos y mínimos de un vector.......................258 VIII.1.xi. Ordenación de un Vector ...................................................259 VIII.2.

Tipos de datos definidos por el usuario (TDU)................261

VIII.2.i.

Asignación de valores ........................................................263

VIII.2.ii. Asignación de valores con With........................................264 VIII.2.iii. Estructuras anidadas..........................................................265 VIII.2.iv. Arreglos de estructuras .....................................................267 VIII.3.

Ejercicios propuestos .........................................................270

LABORATORIO III - AÑO 2008

CAPITULO VIII: ESTRUCTURAS DE DATOS

Página 242

Mg. Ing. Fátima Martínez

PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008

VIII.

CAPITULO VIII Página 243

ESTRUCTURAS DE DATOS

Las estructuras de datos son una representación de la relación lógica existente entre los elementos individuales de datos, determinan: la organización, métodos de acceso, grado de asociatividad y el procesamiento de la información. Pueden ser estructuras de datos estáticas y estructuras de datos dinámicas (Joyanes Aguilar, L, 1990: 366). Las estáticas son aquellas en las que asigna una cantidad fija de memoria cuando se declara la variable (arreglos, archivos, registros, etc.). Sin embargo en numerosas ocasiones se necesitan colecciones de datos que crezcan y reduzcan su tamaño en memoria a medida que el programa progresa. Estas estructuras de datos que pueden modificar la ocupación de memoria se denomina estructuras de datos dinámicas (pilas, colas, listas enlazadas, etc.). Aquí nos dedicaremos a dos tipos de datos más frecuentes: Eje.1)

Datos estructurados simples o estáticos: arreglos.

Eje.2)

Tipos de datos definidos por el usuario (TDU): estructuras.

VIII.1.

Arreglos (Array)

Las variables simples son muy usadas para almacenar pequeñas cantidades de información, pero no son convenientes para grandes cantidades de información muy similar. Por ejemplo, para almacenar los salarios de doscientos empleados, necesitaríamos 200 variables diferentes. Así muchas aplicaciones requieren el procesamiento de múltiples datos que tienen características comunes es decir declarar un conjunto de variables con el mismo tipo de datos. En el ejemplo anterior el conjunto de datos numéricos para cargar los salarios quedaría representado por x1, x2, x3, …, x200 Los datos individuales pueden ser enteros, números en coma flotante, caracteres, etc. (Gotfried, B., 1998:299). En tales situaciones es conveniente colocar los datos en una formación o arreglo donde todos comparten el mismo nombre. Los datos deben ser del mismo tipo y con el mismo tipo de almacenamiento.

Mg. Ing. Fátima Martínez

CAPITULO VIII: ESTRUCTURAS DE DATOS

Mg. Ing. Fátima Martínez

De esta manera un arreglo es una colección de variables del mismo tipo que se referencia por un nombre común (Shildt, H.,1988: 107). Las variables comprendidas en el arreglo o elementos del arreglo se diferencian entre sí por un número de índice (de forma similar a los elementos de un cuadro de lista). La utilización de arreglos representa una gran ventaja para el programador, hace mucho más sencillo el procesamiento de listas de información. Suponga que se desea obtener el promedio de las notas finales en 6 materias de un alumno. En lugar de almacenar las notas en 6 variables diferentes, es mucho más sencillo almacenarlas en un arreglo. Peor todavía si se lleva el registro de los promedios de las temperaturas durante los últimos 90 días. En lugar de almacenarlas en 90 variables distintas, es mucho más sencillo en un arreglo. Una característica importante que diferencia a los datos simples de los estructurados es que para los datos simples cada variable representa un elemento, mientras que en los datos estructurados un identificador (nombre) representa múltiples datos individuales, pudiendo cada uno de ellos ser referenciado individualmente.

VIII.1.i.

Definición

Arreglo, es un conjunto de variables que son del mismo tipo de datos. A cada parte de un arreglo se le denomina elemento. Todos los elementos de un arreglo se referencian con el mimo nombre del arreglo y se almacenan en un conjunto de posiciones consecutivas de memoria (Zhang, T; 2001:190). Dicho de otra manera es una colección finita (hay un último elemento) y ordenada de elementos homogéneos (del mismo tipo de datos) de tamaño fijo (el tamaño del arreglo debe ser conocido). La propiedad ordenada significa que el primer elemento, el segundo, el tercero,..., el enésimo puede ser identificado.

Cada dato individual o elemento de ese arreglo, es referenciado mediante la especificación del nombre del arreglo seguido por uno o más índices cada uno encerrado entre corchetes. El número de índices determina la dimensionalidad del arreglo. Por ejemplo x(i) referencia a una arreglo unidimensional llamado vector, otro y(i)(j) a un arreglo bidimensional (matriz, arreglo de más de una dimensión). El arreglo se caracteriza por: 1. Almacenar los elementos en posiciones contiguas de memoria. Significa que el elemento n-4 precede al elemento n-3 y este a su vez al n-2 así sucesivamente. 2. Tener un único nombre de variable que representa a todos los elementos y estos a su vez se diferencian por un índice. Cada índice es Página 244

PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008

CAPITULO VIII Página 245

expresado por un número entero no negativo. Así un vector de n elementos: x(1), x(2), x(3),…, x(n). 3. Acceso directo o aleatorio a los elementos individuales del arreglo. Cada elemento del arreglo se puede procesar como si fuera una variable simple que ocupa una posición de memoria dada, de manera tal que cada elemento del vector es accesible directamente.

VIII.1.ii. Arreglos estáticos y dinámicos En Visual Basic hay dos tipos de arreglos: estáticos y dinámicos. •

Arreglo estático o de tamaño fijo : aquel que siempre permanece del mismo tamaño, es decir siempre contendrá el mismo número de elementos. Tienen un límite inferior y superior, con un arreglo individual de elementos contiguos dentro de estos límites. El límite superior no puede exceder el rango de los tipos de datos Long (2,147,483,648 al 2,147,483,647).



Arreglo dinámico : aquel que puede cambiar el tamaño de los elementos que contiene en tiempo de ejecución.

VIII.1.iii. Declaración de arreglos estáticos Los arreglos se declaran como las variables ordinarias mediante la sentencia Dim. Deben declararse explícitamente para que así el compilador pueda reservar espacio en memoria para ellos, como se hace con otras variables. Para declarar un arreglo estático se escribe el nombre del arreglo seguido y entre paréntesis el límite superior o máximo índice posible, de la siguiente forma:

Private|Public|Dim nombre(elementos)As Tipo Donde nombre es el nombre del arreglo; elementos indica el máximo índice posible. El Tipo declara el tipo de cada elemento del arreglo. Se puede definir un arreglo con cualquier tipo de datos en Visual Basic. Puede tener tipo de datos enteros, o enteros largos, o string, etc. Lo siguiente crea un arreglo de 5 elementos o datos de tipo Integer:

Dim miArreglo(1 To 5)As Integer Entre paréntesis se declara el rango de capacidad del mismo, es decir la cantidad de datos que podrá contener. El primer número, el 1, indica el límite inferior del mismo y el número 5 indica el límite máximo del arreglo. Mg. Ing. Fátima Martínez

CAPITULO VIII: ESTRUCTURAS DE DATOS

Mg. Ing. Fátima Martínez

Representado gráficamente tiene la siguiente forma: El mismo arreglo pero con ámbito Public:

Public miArreglo(1 To 5) As Integer

1

2

3

4

5

Otra declaración creará un arreglo conteniendo seis elementos del tipo String:

Dim unArreglo(5)As String Cuando NO se indica el limite inferior, se asume que el mismo comienza desde el 0. Representado gráficamente, tiene la siguiente forma: Nombre del arreglo

Máximo índice

Dim unArreglo(5)

As

Tipo de dato

0

1

2

3

4

5

String

Nota: Por defecto el límite inferior de un vector es 0.

Nótese que se puede declarar un vector indicando explícitamente el límite inferior y superior o simplemente definiendo el máximo índice posible (Birnios, B. y Birnios, M.; 2003:227).

Ejemplo de declaración de arreglo

La variable de tipo arreglo Alumno tiene 25 elementos, el primero tiene el índice 1 y el último tiene el índice 25: Dim Alumno(1 To 25) as String

Nota: cada elemento de un vector ocupa memoria, contenga o no datos, por lo tanto no conviene declarar vectores mucho más grandes de lo necesario.

VIII.1.iv. Option Base Predeterminadamente, los arreglos comienzan a numerarse por 0 al declararlos con el número de índice del último elemento, sin embargo, hay una sentencia que se escribe en la parte de declaraciones del módulo o formulario que se esté trabajando para indicar la base predeterminada de los arreglos:

Option Base 0 | 1 ‘comienzan a numerarse por 0 | por 1 Nota: no hace falta escribir Base 0 si se desea que el límite inferior de todos los arreglos sea 0 porque Visual Basic lo asume por defecto.

Página 246

PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008

CAPITULO VIII Página 247

Se declara un vector Nombres de 4 elementos: Option Base 1 Dim Nombres(4) As String

Ejemplo de OPTION BASE

VIII.1.v. Trabajar con elementos del vector En un vector se trabaja con cada elemento de manera similar que con cualquier otra variable, pero poniendo entre paréntesis el número de índice del elemento en cuestión. Por ejemplo: Dim otroArreglo(3)As Integer 0

1

2

3

3600

-366

1234

8

otroArreglo(0) = 3600

otroArreglo(1) = -366

otroArreglo(2) = 1234

otroArreglo(3) = 8

Si quisiera asignarse a una etiqueta de nombre lblEntero el valor del elemento de índice 2, se utilizará la siguiente sentencia: lblEntero.Caption = otroArreglo(2)

1. Ejercicio La aplicación lee 10 números y calcule e imprima su promedio.

El código de los eventos Option Explicit Option Base 1

'Para empezar en el índice 1

Dim C As Integer, suma As Double Dim X(10) As Double Private Sub cmdLimpia_Click() 'Borra el contenido de todos los controles txtNumero.Text = "" For C = 0 To 2 lblResul(C).Caption = "" Next C End Sub Private Sub cmdSalir_Click()

Mg. Ing. Fátima Martínez

‘Declara un vector de 10 elementos

CAPITULO VIII: ESTRUCTURAS DE DATOS

Mg. Ing. Fátima Martínez

End End Sub Private Sub txtNumero_KeyPress(KeyAscii As Integer) 'Cuando presiona Enter y si se escribió algo en la caja de texto If KeyAscii = 13 And txtNumero "" Then C=C+1 'Carga el elemento del vector con el valor ingresado X(C) = Val(txtNumero.Text) suma = suma + X(C) lblResul(0).Caption = C

‘Muestra en una etiqueta la cantidad

lblResul(1).Caption = Str$(suma)

'Muestra en una etiqueta la suma

txtNumero.Text = ""

‘Borra la caja de texto

End If If C = 10 Then lblResul(2).Caption = Str$(suma / 10)

'Muestra el promedio

txtNumero.Enabled = False End If End Sub

VIII.1.vi. Funciones de VB: LBound y UBound La función Lbound devuelve un valor de tipo Long con el límite inferior y

UBound el límite superior de un arreglo. Sus sintaxis: LBound (arreglo [,dimensión])

y

UBound (arreglo [,dimensión])

Si se trabaja con vectores, el parámetro dimensión no hace falta usar. Son ideales cuando se trabaja con vectores dinámicos para conocer su tamaño.

Ejemplos de las funciones LBOUND y UBOND

Dim LimiteInf As Integer Dim LimiteSup As Integer Dim Nombres(10) As String LimiteInf = LBound(Nombres) ‘ Devuelve 0 LimiteSup = UBound(Nombres) ‘ Devuelve 10

Ejemplo de LBound y UBound Para recorrer todos los elementos de un vector mediante un bucle For.

Página 248

For x = LBound(vector) To UBound(vector) Print vector(x) ….. ….. Next

PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008

CAPITULO VIII Página 249

VIII.1.vii. Arreglos dinámicos Los arreglos vistos hasta aquí son de tamaño fijo, mantienen su tamaño original, la cantidad de elementos y dimensiones que tiene se define en la declaración y no se puede variar. Esto hace que muchas veces estén sobredimensionados o sea que tengan más o menos elementos de los que se necesitan. Por este propósito existen los arreglos dinámicos que pueden variar su tamaño en tiempo de ejecución. Esto proporciona gran flexibilidad y la ventaja de no desperdiciar memoria cuando se crean vectores más grandes de lo necesario. Visual Basic, contiene los mecanismos apropiados para crear arreglos dinámicos, que pueden cambiar su tamaño para ajustarse a las necesidades del problema, incluso si perder los elementos de datos que ya contenga. Estos arreglos se declaran como los estáticos pero sin indicar su rango (escribir sólo los paréntesis), su forma general de declaración es la siguiente:

Private|Public |Dim nArregloDinam()As Tipo Donde nArregloDinam es el nombre del arreglo dinámico que se declara. Para cambiar el número de elementos, así como el límite superior e inferior en un arreglo dinámico se utiliza la sentencia Redim que es ejecutable. Esto se realiza de la siguiente forma general:

Redim nArregloDinam(elementos) Esta instrucción puede ser usada cada vez que se desee redimensionar. También es importante destacar que se puede modificar la magnitud de cada dimensión, pero no la cantidad de dimensiones. Se declara un vector dinámico Nombres: Dim Nombres() As String Se cambia el tamaño del vector Nombres: ReDim Nombres(1 to 4) Ejemplo de la declaracón de un arreglo dinámico

Se inicializa el vector Nombres: Nombres(1)= “Pablo” Nombres(2) = “Marta” Nombres(3) = “José” Nombres(4) = “Nicolás”

Mg. Ing. Fátima Martínez

CAPITULO VIII: ESTRUCTURAS DE DATOS

Mg. Ing. Fátima Martínez

2. Ejercicio Aplicación que calcula el promedio de N números. En la aplicación se trabaja con un vector dinámico. Su dimensión varía de acuerdo con la cantidad ingresada por el usuario.

Código de los Eventos Option Explicit Dim C As Integer, N As Integer, Suma As Double Dim X() As Double

'Declara un vector dinámico

Private Sub cmdLimpia_Click() Dim i As Integer C=0 txtNumero = "" txtCantidad = "" For i = 0 To 2 lblResul(i) = "" Next i txtCantidad.Enabled = True txtCantidad.SetFocus End Sub Private Sub cmdSalir_Click() End End Sub Private Sub Form_Activate() C=0 txtNumero.Enabled = False txtCantidad.SetFocus

'Deshabilita donde ingresa el número

'pone el foco en la cantidad

End Sub Private Sub txtCantidad_KeyPress(KeyAscii As Integer) If KeyAscii = 13 And Len(txtCantidad) 0 Then N = Val(txtCantidad.Text) ReDim X(1 To N) As Double

'Redimensiona el vector dinámico

txtNumero.Enabled = True

' habilita la caja de texto número

txtNumero.SetFocus txtCantidad.Enabled = False

'pone el foco en el número 'deshabilita cantidad

End If End Sub Private Sub txtNumero_KeyPress(KeyAscii As Integer) If KeyAscii = 13 And Len(txtNumero) 0 Then C=C+1

Página 250

PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008

CAPITULO VIII Página 251

X(C) = Val(txtNumero.Text) Suma = Suma + X(C) lblResul(0).Caption = C lblResul(1).Caption = Str$(Suma) txtNumero.Text = "" End If If C = N Then lblResul(2).Caption = Str$(Round(Suma / N,2)) txtNumero.Enabled = False

'Deshabilita la caja de número

End If End Sub

Redim y Preserve Cada vez que es ejecutada la sentencia Redim los valores actualmente almacenados en el arreglo se pierden, ya que Visual Basic reestablece todos los elementos a su valor inicial por default. Nota: a menos que se indique lo contrario, cuando se redimensiona un vector se pierde el contenido que tenía previamente.

Afortunadamente es posible cambiar el tamaño del arreglo sin perder los datos almacenados en este, se emplea la sentencia Redim con la palabra reservada Preserve .

Redim Preserve nArregloDinam(elementos)

3. Ejercicio Aplicación que carga dos listas con datos provenientes de un arreglo dinámico. Para la primera lista el vector tiene asignada una cantidad igual a 4, para la segunda lista tiene 7 elementos. Para conservar sus valores de la primera lista se utiliza Preserve.

Código del evento Click del bot ón OK Private Sub cmdOk_Click() 'Declara un vector dinámico Dim Num() As Integer, i As Integer, j As Integer 'Dimensiona el vector con cuatro elementos

Mg. Ing. Fátima Martínez

CAPITULO VIII: ESTRUCTURAS DE DATOS

Mg. Ing. Fátima Martínez

ReDim Num(1 To 4) As Integer For i = 1 To UBound(Num) Num(i) = i * 5 lst1.AddItem Num(i) Next i 'Redimensiona el vector y lo preserva de que se borre el anterior ReDim Preserve Num(1 To 7) As Integer For j = i To UBound(Num) Num(j) = j * 10 Next j 'Pasando a la lisa 2 los elementos del arreglo For i = 1 To UBound(Num) lst2.AddItem Num(i) Next i End Sub

VIII.1.viii.

Funciones que devuelven arreglos

Visual Basic 6 brinda la posibilidad de que las funciones devuelvan arreglos y tipos de datos definidos por el usuario, con lo cual otorga mayor flexibilidad a las funciones que se crean. La forma general de la declaración de una función que devuelve un arreglo es la siguiente:

Public|Private Function nomFuncion([argumentos])As T ipo() Su declaración es igual a la de cualquier función pero seguido del tipo de dato y un par de paréntesis. Dentro de la función se debe declarar un arreglo dinámico del mismo tipo de dato devuelto por la función y luego redimensionarlo, asignarle los valores al vector y devolver este arreglo asignándolo al nombre de la función (Castillo, E. G; 1998:32).

4. Ejercicio La aplicación carga una lista con elementos de un arreglo de 20 números enteros generados al azar en tiempo de ejecución. En una caja de texto muestra el elemento seleccionado y su posición, en una etiqueta.

Página 252

PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008

CAPITULO VIII Página 253

El código del evento Click del botón cmdLlena Private Sub cmdLlena_Click() 'llena el arreglo de tamaño n Dim i As Integer, n As Integer Dim Arreglo() As Integer

'Declara un vector dinámico

'Limpia la lista de números por si tenía algún elemento lstNumeros.Clear Randomize n = 20 'El arreglo se carga mediante una función Arreglo() = CargArreglo(n)

'Manda la cantidad de elementos

'Agrega cada elemento del vector a la lista de números For i = 0 To n - 1 lstNumeros.AddItem Arreglo(i) Next i End Sub Private Sub lstNumeros_Click() 'Evento Click para mostrar el elemento seleccionado lblElem.Caption = lstNumeros.ListIndex txtElem.Text = lstNumeros.List(lstNumeros.ListIndex) End Sub

Función que devuelve un vector de enteros Function CargArreglo(tama As Integer) As Integer() 'Función de tipo arreglo de enteros Dim Temp() As Integer, i As Integer 'Crea un vector temporal ReDim Temp(tama) 'Carga el vector con números generados aleatoriamente For i = 0 To tama num = Int(Rnd() * 60) + 1 Temp(i) = Str(num) Next 'La funcion devuelve un arreglo CargArreglo = Temp End Function

VIII.1.ix. Funciones Join, Split y Filter Las funciones Join , Split y Filter relacionadas con vectores y cadenas de caracteres fueron incorporadas en la versión 6.0 de Visual Basic. Función Join(vector [,delimitador])

Realiza

Parámetros

Devuelve una cadena creada

Vector: nombre del vector que contiene

por la unión de varias

las subcadenas a unir.

Mg. Ing. Fátima Martínez

CAPITULO VIII: ESTRUCTURAS DE DATOS

Función

Mg. Ing. Fátima Martínez

Parámetros

Realiza subcadenas contenidas en un

Delimitador (opcional): carácter usado

vector.

para separar las subcadenas en la cadena a devolver. Por defecto, se utiliza el carácter espacio (“ ”). Expresión: contiene todas las subcadenas con sus delimitadores. Si la expresión no

Split(expresión [,delimitador [,contador]])

existe devuelve un vector vacío. Devuelve

un

vector

que

contiene un número específico de subcadenas.

Delimitador (opcional): carácter usado en el texto para separar las subcadenas. Por defecto se usa el carácter espacio (“ ”). Contador (opcional): número máximo de subcadenas a colocar en el vector. Vector: nombre del vector donde se va a buscar las subcadenas.

Filter(vector, cadena [,modo])

Filtra subcadenas de un vector que cumplan cierto criterio.

Cadena a buscar (o a ignorar) Modo

(opcional):

valor

booleano

que

indica si hay que devolver subcadenas que incluyan o excluyan el valor del parámetro cadena.

VIII.1.ix.1.

Función Join

Dim micadena as string Dim vector(1 To 3) As String vector(1) = "Carlos" vector(2) = "Pedro" vector(3) = "Juan" micadena = Join (vector, "-") Ejemplo de la función Join

Ahora ejecutando Join , la variable micadena pasaría a valer: "Carlos-Pedro-Juan" Si no se especifica un delimitador, Visual Basic utilizará por defecto un espacio vacío o en blanco (" ") para separar cada subcadena.

VIII.1.ix.2.

Función Split

Esta función hace el trabajo inverso de la función Join.

Página 254

PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008

CAPITULO VIII Página 255

Se utiliza para rellenar un vector dinámico que contiene un número de subcadenas a partir de una cadena que se le pasa como parámetro a la función.

Ejemplo de la función Join

Private Sub Form_Load() 'Una variable para almacenar una cadena Dim Micadena As String 'Vector dinámico Dim Vector() As String 'se le asigna un valor a la variable Micadena = "maria/natalia/romina" 'se ejecuta la función Split Vector = Split(Micadena, "/") End Sub

Ahora el vector dinámico pasaría a contener los siguientes valores: Vector(0) = "maría" Vector(1) = "natalia" Vector(2) = "romina"

IMPORTANTE: Al definir el vector que contendrá lo devuelto por la función Split, no se debe indicar ningún rango, ya que devuelve un vector cuya cantidad de elementos no se conoce, aunque se sabe que el primer elemento tendrá el índice 0.

5. Ejercicio La siguiente aplicación carga los elementos de un vector desde una lista de nombres. El botón de comando cmdUne utiliza la función Join. El botón cmdVector utiliza la función Split y presenta los elementos del nuevo vector.

Mg. Ing. Fátima Martínez

CAPITULO VIII: ESTRUCTURAS DE DATOS

Mg. Ing. Fátima Martínez

El código de los eventos y Procedimientos Option Explicit Dim Nombre(3) As String Private Sub cmdUne_Click() lblNombres = Join(Nombre, "-") 'Une los elementos del vector Nombre End Sub Private Sub cmdVector_Click() Dim i As Integer Dim Nombres() As String 'IMPORTANTE no debe declararse con un rango lblElementos.Visible = True Nombres = Split(lblNombres, "-") 'Carga el vector Nombres For i = 0 To 3 lblLista(i) = Nombres(i) Next End Sub Private Sub Form_Load() Dim i As Integer For i = 0 To 3 lstNombres.ListIndex = i Nombre(i) = lstNombres.List(lstNombres.ListIndex) Print Next lstNombres.ListIndex = 0 End Sub

El primer parámetro de la función es la cadena que queremos separar o desglosar, en este caso es el TextBox

6. Ejercicio Simple de la función Split

El segundo parámetro delimitador que tomará separar los datos, en constante de salto de VbNewLine.

es el carácter en cuenta para este caso es la carro VbCrlf o

La función Split se la debe asignar a un arreglo dinámico de tipo String de esta forma: Dim MiArray () As String

Página 256

PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008

CAPITULO VIII Página 257

Mediante la función Split se puede obtener un arreglo con las líneas que contiene un TextBox multilinea y luego pasar las líneas a un ListBox.

Los controles son: una lista “Lista”, un Textbox multilínea “Texto” y un botón de comando “cmdSplit”. El código de los procedimientos Private Sub cmdSplit_Click() 'arreglo o vector dinámico para almacenar las lineas mediante Split Dim Lineas() As String Dim i As Integer 'borra el listbox Lista.Clear ' Le pasa el textobx (el dato ), y el caracter delimitador Lineas = Split(Texto, vbNewLine) 'Recorre el arreglo y carga los elementos del array en el ListBox For i = LBound(Lineas) To UBound(Lineas) Lista.AddItem Lineas(i) Next End Sub Private Sub Form_Load() cmdSplit.Caption = " Aceptar " Texto = "Lunes" & vbNewLine & _ "Martes" & vbNewLine & _ "Miercoles" & vbNewLine & _ "Jueves" & vbNewLine & _ "Viernes" & vbNewLine & _ "Sábado" & vbNewLine & _ "Domingo" End Sub

VIII.1.ix.3.

Función Filter

La función Filter se utiliza para filtrar subcadenas de un vector dependiendo de un determinado criterio de búsqueda. Los parámetros que lleva la función son los siguientes:

Filter (vector_donde_buscar, cadena_a_buscar, valor_booleano ) El valor booleano indica si incluir o excluir la cadena. Mg. Ing. Fátima Martínez

CAPITULO VIII: ESTRUCTURAS DE DATOS

Mg. Ing. Fátima Martínez

'Vector Dim Alumnos(1 To 4) As String 'Vector dinámico para almacenar el resultado Dim Resultado() As String

Ejemplo de la función Filter

Alumnos(1) Alumnos(2) Alumnos(3) Alumnos(4)

= = = =

"Luciano" "Lucas" "juan" "Natalia"

'Ejecutamos Filter Resultado = Filter(Alumnos, "Lu", True) 'Se muestra el vector dinámico "resultado" MsgBox Resultado(0), vbInformation 'Luciano MsgBox Resultado(1), vbInformation 'Lucas

IMPORTANTE: Para conocer la cantidad de elementos que devolvió la función Filter podemos usar la función UBound.

VIII.1.x. Valores máximos y mínimos de un vector Una operación frecuente es determinar el mínimo o máximo valor almacenado en un vector. El diseño suele realizarse con funciones o procedimientos.

Algoritmo Máximo 1. Se supone que el primer elemento del vector es el mayor. 2. Para cada elemento del vector: a. Si el elemento actual es mayor que el mayor, guardar el subíndice del elemento actual como subíndice del mayor (utilizar una variable auxiliar Aux).

7. Ejercicio Función para encontrar el Máximo valor de un vector.

La función recibe un vector de números de coma flotante y retorna un valor del mismo tipo; n es la cantidad de elementos del vector. Function Maximo(Vec() As Double, n As Integer) As Double Dim i as integer, Aux as Double Aux = Vec(0) For i = 1 to n - 1

Página 258

PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008

CAPITULO VIII Página 259

If Vec(i) > Aux then Aux = Vec(i) End if Next End Function

VIII.1.xi. Ordenación de un Vector La ordenación o clasificación de datos (sort en inglés) es una operación consistente en disponer un conjunto de datos en algún determinado orden con respecto a uno de los acampos de elementos del conjunto […] Los elementos numéricos se pueden ordenar en orden creciente o decreciente de acuerdo al valor numérico del elemento. (Joyanes Aguilar, L.; 1990:412) Muchas aplicaciones requieren que se ordenen ascendentemente o descendentemente los elementos de un vector. Existen muchos algoritmos que permiten ejecutar esta tarea, diferenciándose por su complejidad y eficiencia. Dos criterios se suelen guiar a la hora de decidir qué algoritmo es el más eficiente: 1. tiempo menor de ejecución en computadora; 2. menor número de instrucciones. No siempre es fácil efectuar estas medidas, entonces lo que se utiliza como medida de su eficiencia es el número de comparaciones efectuadas entre elementos. Uno de los algoritmos de ordenamiento de vectores más simple (aunque no muy eficiente) es el de ordenación por selección. Para ordenar ascendentemente un vector numérico el algoritmo de ordenación por selección utiliza dos bucles anidados, de manera tal que se realizan recorridos sucesivos por el arreglo para localizar el elemento mayor y colocarlo en el lugar que le corresponde en la lista ordenada. 1. Se busca el elemento más pequeño de la lista. 2. S e lo intercambia con el elemento ubicado en la primera posición de la lista. 3. Se busca el segundo elemento más pequeño de la lista. 4. Se lo intercambia con el elemento que ocupa la segunda posición en la lista. 5. Se repite el proceso hasta que se haya ordenado toda la lista.

Mg. Ing. Fátima Martínez

CAPITULO VIII: ESTRUCTURAS DE DATOS

Mg. Ing. Fátima Martínez

8. Ordenación por Selección Aplicación que ordena una lista de números ingresados en tiempo de ejecución dentro de un PictureBox mediante una caja de texto.

El código de los eventos Option Explicit Const Tama = 10 Dim c As Integer Dim Temp(1 To Tama) As Double Private Sub txtNumero_KeyPress(KeyAscii As Integer) If KeyAscii = 13 And txtNumero "" Then c=c+1 Temp(c) = Val(txtNumero.Text) Picture1.Print Temp(c) txtNumero = "" If c = Tama Then txtNumero.Enabled = False End If End If End Sub Private Sub cmdOrdenar_Click() Dim maxIndex As Integer Dim X() As Double, i As Integer X() = OrdenaVec(Temp, Tama)

'Manda a la Función para ordenar

lblNumerosOrdena.Visible = True Picture1.Cls For i = 1 To Tama Picture1.Print X(i) Next End Sub

El código dentro del módulo Option Explicit Dim i As Integer, j As Integer

El código de la función OrdenaVec() Function OrdenaVec(Vec() As Double, n As Integer) As Double()

Página 260

PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008

CAPITULO VIII Página 261

Dim maxIndex As Integer, Temp As Double Dim X() As Double

'Declara un vector dinámico temporal

ReDim X(n) As Double

'redimensiona el vector

X = Vec

'Le asigna al vector temporal los elementos del vector original

For i = n To 1 Step -1 maxIndex = 1 'Se determina el índice del elemento mayor en el conjunto x(1) - x(i) For j = 1 To i If X(j) > X(maxIndex) Then maxIndex = j End If Next j 'Se intercambian los valores de x(i) y el máximo encontrado en el recorrido de arriba Temp = X(i) X(i) = X(maxIndex) X(maxIndex) = Temp Next i OrdenaVec = X

'Devuelve el vector ordenado

End Function

VIII.2.

Tipos de datos definidos por el usuario (TDU)

Hasta aquí se han visto prácticamente la totalidad de tipos de variables que Visual Basic soporta, también cómo agrupar variables para crear Arreglos. Ahora se verá cómo crear nuestras propias variables, que en Basic son del tipo definidas por el usuario (TDU o UDT User Defined Type). En realidad no es crear una variable, sino un tipo de variable especial en el que se pueden agrupar variables de distintos tipos; es lo que en otros lenguajes se llaman estructuras. A veces no es suficiente con el tipo de dato que Visual Basic proporciona para almacenar el dato. Por ejemplo, si se desea que una variable guarde datos angulares (grados, minutos, segundos y décimas de segundo), no hay una variable de este tipo. Por ello Visual Basic permite definir tipos de datos que combinen otros existentes, lo cual es muy útil para crear variables “personalizadas”. Una estructura (según la nomenclatura típica del lenguaje C) es un nuevo tipo de datos, un tipo definido por el usuario, que puede ser manipulado de la misma forma que los tipos predefinidos (Int, Double, String, ...). Una estructura puede definirse como una colección o agrupación de uno o más tipos diferentes de variables que se referencia bajo un nombre, proporcionando un medio conveniente de mantener junta información relacionada. En general cada elemento de la estructura esta relacionado lógicamente con los otros.

Mg. Ing. Fátima Martínez

CAPITULO VIII: ESTRUCTURAS DE DATOS

Mg. Ing. Fátima Martínez

Para crear una estructura con Visual Basic 6.0 hay que utilizar la sentencia Type ... End Type . Esta sentencia solamente puede aparecer en la sección General o de declaraciones de un módulo. Su declaración debe ser definida en términos de sus miembros individuales en un bloque de código como el siguiente:

Type nombre SubV1 As tipo SubV2 As tipo … End Type

Se utiliza la palabra clave Type.

Donde: nombre es el nombre del nuevo tipo de variable que se define, SubV1 es una subvariable que lo compone, SubV2 es otra subvariable que lo compone. Puede haber tantas subvariables como se necesiten. Inclusive a su vez una subvariable puede ser de otro tipo de estructura. Los tipos definidos por el usuario pueden declararse como Private o como Public en un módulo estándar o de clase y sólo como Private en un formulario mediante la palabra clave apropiada: Private | Public Type MiTipo Para el mismo tipo definido por el usuario se pueden declarar variables locales, variables privadas de módulo o variables públicas de módulo:

Dim nVar as MiTipo En el ejemplo de las medidas angulares, puede declararse una estructura como la siguiente:

Ejemplo de una variable estructura

Type Angulo Grados As Integer Minutos As Byte Segundos As Byte Decimas As Byte End Type Si quisiera guardarse una variable de este tipo, se declara la variable y luego se le asigna el valor, en el ejemplo, un ángulo de 48º 57’ 21.67”. Public Angulo1 As Angulo Angulo1.Grados=48 Angulo1.Minutos=57 Angulo1.Segundos=21 Angulo1.Decimas=67

Página 262

PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008

VIII.2.i.

CAPITULO VIII Página 263

Asignación de valores

Para acceder a cada miembro de esta variable se consigue a través de su nombre seguido del operador punto (como si fuesen propiedades), tanto para recuperar su valor como para asignarle un valor: nVar.SubV1 = valor La asociatividad del operador punto (.) es de izquierda a derecha. La información sobre el nombre y la dirección encontrada en una lista de correos sería normalmente representada en una estructura. Después de decidir sobre los miembros se debe asignar a cada uno su correspondiente tipo de dato: Private Type Persona Nombre As String * 25 Calle As String * 30 Ciudad As String * 15 Provincia As String * 15 CP As Integer End Type

Ejemplo de una variable estructura

Se declara la variable de este tipo: Dim miColega as Persona Asigna el código postal 12345 al campo CP: miColega.CP = 12345 Text1.text = miColega.CP La figura siguiente muestra la estructura de las direcciones en una lista de correo que representa en forma gráfica los tipos de datos presentes en la misma.

Mg. Ing. Fátima Martínez

CAPITULO VIII: ESTRUCTURAS DE DATOS

Type Persona Nombre As String Calle As String Ciudad As String Provincia As String CP As Integer End Type

Mg. Ing. Fátima Martínez

Persona

Dim miColega as Persona

Nombre

Miembro1

Calle

Miembro2

Ciudad

Miembro3

Provincia

Miembro4

CP

Miembro5

VIII.2.ii. Asignación de valores con With Para no tener que repetir el nombre de la variable, en Visual Basic se utiliza la instrucción With (vista anteriormente) de la siguiente manera:

With miColega .Nombre = “Martín Fierro” .Calle = “José Hernández” .Ciudad = “San Martín” .Provincia = “La Pampa” End With Visual Basic ya sabe que estamos refiriéndonos a miColega porque esa es la variable que se usa después de With. Es más claro usando With.

9. Ejercicio Aplicación para pedir al usuario información sobre alumnos y sus notas. Para mantener el ejemplo razonablemente breve se definen solamente dos alumnos.

Código de los eventos Option Explicit 'Se define un tipo de datos Alumno

Página 264

PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008

CAPITULO VIII Página 265

Private Type Alumno Nombre As String * 15 'Miembro Nombre del tipo string de 15 caracteres Edad As Byte ' Miembro Edad del tipo byte Nota As Byte 'Miembro Nota del tipo byte End Type 'Total de byte = 17 'Se declaran dos variables del tipo Alumno Dim alu1 As Alumno, alu2 As Alumno Dim resp1 As String, resp2 As String Private Sub cmdCarga_Click() Dim AluNum As String resp1 = MsgBox("Ingresa datos del alumno?", vbYesNo + vbInformation + vbDefaultButton1, "Datos del alumno") If resp1 = vbYes Then AluNum = "Alumno 1" 'Se asigna a cada miembro de la variable alu1 un valor alu1.Nombre = InputBox("Ingrese el nombre", AluNum, "") alu1.Edad = InputBox("Ingrese la edad", AluNum, "") alu1.Nota = InputBox("Ingrese la nota", AluNum, "") End If resp2 = MsgBox("Ingresa datos del segundo alumno?", vbInformation + vbDefaultButton1, "Datos del alumno")

vbYesNo

+

If resp2 = vbYes Then AluNum = "Alumno 2" 'Se asigna a cada miembro de la variable alu2 un valor alu2.Nombre = InputBox("Ingrese el nombre", AluNum, "") alu2.Edad = InputBox("Ingrese la edad", AluNum, "") alu2.Nota = InputBox("Ingrese la nota", AluNum, "") End If End Sub

VIII.2.iii. Estructuras anidadas Los tipos definidos, no sólo sirven para "mezclar" variables del mismo tipo, sino también variables de varios tipos, incluso variables de tipos definidos. Es decir su vez, un miembro de una estructura puede ser otra estructura. Type Fecha

Ejemplo de estructuras anidadas

Dia

As Integer

Mes

As Integer

Anio As Integer End Type Type Alumno

Mg. Ing. Fátima Martínez

Alta

As Fecha

Nombre

As String

Direccion

As String * 40

CAPITULO VIII: ESTRUCTURAS DE DATOS

Mg. Ing. Fátima Martínez

Telefono

AS Long

DNI

As Long

End Type En estos casos se pueden anidar varios Withs... unos dentro de otros, pero siempre el PUNTO hará referencia al último que se ha puesto. Type Empleado Personales As DatePers Direccion As Domicilio Fecha As Date Profesional As DateProf End Type Dim UnEmpleado As Empleado

Ejemplo de estructuras anidadas La estructura Empleado contiene campos que son a su vez otra estructura.

With UnEmpleado With Personales .Nombre = “María Antonieta” .Genero = “F” .Estado = “Divorciada” End With With Dirección .Calle = “San Lorenzo” .Nro = 64 .Ciudad = “S. M. de Tucumán” .Provincia = “Tucumán” End With End With

Página 266

PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008

CAPITULO VIII Página 267

VIII.2.iv. Arreglos de estructuras Lo más importante es que se puede definir un vector cuyos elementos sean un tipo definido por el usuario. Tomando el ejemplo:

Ejemplo Arreglo de Estructuras

Private Type Dire Nombre As String * 25 Calle As String * 30 Ciudad As String * 15 Provincia As String * 15 CP As Integer End Type Se declara un vector de este tipo: Dim Persona(1 to 10) as Dire

10. Ejercicio Aplicación en la que se ingresan el código de películas alquiladas, su género y la fecha de su alquiler. Al finalizar se muestran en un segundo formulario la lista de las películas alquiladas ordenadas por fecha.

El código de los eventos en el Primer Formulario Option Explicit

Mg. Ing. Fátima Martínez

CAPITULO VIII: ESTRUCTURAS DE DATOS

Mg. Ing. Fátima Martínez

Dim n As Integer 'Declara una variable global para contador Private Sub cmdAlquila_Click() 'Incrementa en 1 el número de película para cada ingreso n=n+1 'El caption del frame muestra el número de película a ingresar frmPeli.Caption = "Pelicula Nº " & Str(n) 'Redimensiona el arreglo a la cantidad n de peliculas alquiladas ReDim Preserve Alquiladas(n) As Pelicula 'Pone en forma fecha corta txtFecha = Format(txtFecha, "dd/mm/yy") 'Llama a un procedimiento para ingresar al arreglo de películas alquiladas Call CargaAlquiler(n, txtPeli, cmbGenero, txtFecha) 'Pregunta si continua ingresando If MsgBox("Desea ingresar otra?", vbYesNo, "Alquiler Nº " & n) = vbYes Then 'Si continúa, limpia los controles txtPeli = "" txtFecha = "" cmbGenero.ListIndex = -1 'Pone el foco en la primer caja de texto txtPeli.SetFocus 'Cambia el caption del marco frmPeli.Caption = "Pelicula Nº " & Str(n + 1) Else 'Si no continua pasa el foco al botón mostrar cmdMuestra.SetFocus End If End Sub Private Sub cmdMuestra_Click() 'Llama al procedimiento Call Muestra(Alquiladas) End Sub

El código de los eventos en el Segundo Formulario Option Explicit Private Sub cmdOrdena_Click() Call Ordena(Alquiladas)

'Manda a ordenar el vector

Call Muestra(Alquiladas)

'Muestra el vector

End Sub Private Sub cmdSalir_Click() End End Sub Private Sub cmdVolver_Click() Form2.Hide Form1.Show End Sub

El código de los procedimientos Sub en el Módulo Option Explicit Option Base 1 Type Pelicula codigo As String * 6

'Para el código de la película

genero As String * 15

'Para el genero de la película

fecha As Date

'Para la fecha en la que se alquila

Página 268

PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008

CAPITULO VIII Página 269

End Type Public Alquiladas() As Pelicula 'Declara un arreglo dinámico del tipo Pelicula Public Sub CargaAlquiler(i As Integer, peli As String, gn As String, fch As Date) With Alquiladas(i) .codigo = peli .genero = gn .fecha = fch End With End Sub Public Sub Muestra(Arreglo() As Pelicula) Dim j As Integer Form1.Hide Form2.Show

'Oculta el formulario principal 'Muestra el segundo formulario

Form2.Cls Form2.Print "Nº"; Tab(6); "Código"; Tab(17); "Genero"; Tab(35); "Fecha" Form2.Print "________________________________________________" Form2.Print For j = 1 To UBound(Arreglo) With Arreglo(j)

'Desde el índice 1 hasta el límite superior 'Presenta en el formulario 2.

Form2.Print j; Tab(6); .codigo; Tab(17); .genero; Tab(35); .fecha End With Next End Sub

El 2º Formulario presenta los elementos del vector Alquiladas con sus respectivos campos

El código del procedimiento para ordenar por Fecha Public Sub Ordena(Arreglo() As Pelicula) 'ordena por BURBUJA Dim n As Integer, i As Integer, j As Integer Dim Temp() As Pelicula

Mg. Ing. Fátima Martínez

CAPITULO VIII: ESTRUCTURAS DE DATOS

Mg. Ing. Fátima Martínez

n = UBound(Arreglo) ReDim Temp(n) For i = 1 To n - 1 For j = 1 To n - i If (Arreglo(j).fecha > Arreglo(j + 1).fecha) Then Temp(j) = Arreglo(j) Arreglo(j) = Arreglo(j + 1) Arreglo(j + 1) = Temp(j) End If Next j Next i End Sub

El 2º Formulario presenta los elementos del vector Alquiladas ordenado por fecha

VIII.3.

Ejercicios propuestos

Ejercicio 1)Crea una aplicación en la cual ordenes alfabéticamente en forma creciente, mediante el método de la burbuja los nombres de 30 personas ingresados en tiempo de ejecución a una caja PictureBox. El método de la Burbuja compara el contenido de elementos adyacentes, si el anterior es mayor al siguiente intercambia estos elementos entre sí, continúa con el proceso hasta la penúltima posición dentro del arreglo. En la primera pasada deja el mayor al final. Repite el proceso hasta completar la lista. Ejercicio 2)Elabora una aplicación en la cual simules un juego con tarjetas de dos caras. El arreglo será de 10 valores. Deberás seleccionar una opción para mostrar la tarjeta en forma secuencial o aleatoria. Observa la imagen para ingresar los controles.

Página 270

PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008

Muestra el contenido de la tarjeta por el lado A.

Muestra el contenido de la tarjeta por el lado B.

CAPITULO VIII Página 271

Botón para mostrar el contenido del lado A. Deshabilita luego de mostrar. Botón para mostrar el contenido del lado B. Deshabilita luego de mostrar. Opciones para la manera de seleccionar las tarjetas.

Ejercicio 3)Implementa una aplicación que lea una lista de números y calcule su promedio . Solicita al usuario el ingreso de cada uno de ellos mediante una caja de InputBox e incorpóralos a un listBox. Debes mostrar el resultado en una caja de mensaje. Ejercicio 4)Un video Club necesita llevar un control de las películas alquiladas en el día, y el importe en pesos del día teniendo en cuenta que el alquiler por horas cuesta $5. Debes realizar dicho trabajo, para ello utilizarás una estructura con dos campos: género (comedia, dramática, terror y ciencia ficción) y el código de la película alquilada. Al finalizar el día además de presentar por pantalla cantidad de películas alquiladas y cantidad de pesos debe mostrar la cantidad de películas según el género. Ejercicio 5)Realizar una aplicación en la que ingrese la hora del día en formato de horas, minutos y AM/PM y encuentre su correspondiente en formato militar (ej. en formato militar 2220 es 10:20 PM en formato AM/PM). Debes tener en cuenta todas las posibilidades de error en el ingreso de la hora, por ej. que el usuario no haya ingresado AM o PM.

Ejercicio 6)Se leen dos vectores A y B de orden N. Los vectores son numéricos y cada elemento tiene un valor de 1 dígito. Se debe sumar por celda los elementos correspondientes de cada vector como si fuese la suma de dos números decimales. Se genera un

Mg. Ing. Fátima Martínez

CAPITULO VIII: ESTRUCTURAS DE DATOS

Mg. Ing. Fátima Martínez

tercer vector C con los dígitos resultantes de la suma antes mencionada, presentar C. NOTA: Tener en cuenta el acarreo. Ingresa los elementos de los vectores como si se tratara de 2 números en sendas cajas de texto. Debes tener en cuenta las teclas que se pueden presionar, por ejemplo si se desea borrar el digito anterior (tecla backSpace) o cualquier otra que no sea número. Para terminar el ingreso del primer número teclea [Enter], esto hará que se pase a la siguiente caja de texto para ingresar el 2º número a sumar. La cantidad de dígitos ingresados deberá ser la misma para el siguiente número. Al presionar [Enter] en la segunda caja de texto se pasará el foco al botón + que efectúa la suma dígito a dígito de los vectores.

El botón + se activa al finalizar el ingreso de los dos números y los cuadros de texto quedan deshabilitados. El botón Borra limpia las cajas de texto y regresa todo a la situación inicial. Muestra los resultados de las operaciones en el formulario.

BIBLIOGRAFÍA CONSULTADA Y RECURSOS EN LA WEB Nombre

Autor/Año

Edición, Editorial / Dirección del Sitio

Microsoft Visual Basic 6.0. Manual de Referencia Programación en Turbo Pascal. Versiones 4.0, 5.0 y 5.5

Birnios, B. y Birnios, M.; 2003

Manuales USERS; MP Ediciones; Buenos Aires; Argentina.

Joyanes Aguilar, L, 1990

Mc Graw Hill, Perú.

Programación en C

Gotfried, B., 1998

Mc Graw Hill, Madrid.

Shildt, H.,1988

Mc Graw Hill, Madrid.

Zhang, T; 2001

Prntice Hall, México.

C Manual de Referencia Aprendiendo C en 24 horas

Página 272

Get in touch

Social

© Copyright 2013 - 2024 MYDOKUMENT.COM - All rights reserved.