sábado, 31 de mayo de 2008

foo fighters "chat" unidad VII

7 Arreglos

Un arreglo, array en inglés, es un grupo consecutivo de localidades de memoria que tienen el mismo nombre y el mismo tipo. Para referirnos a una localidad o elemento particular de un arreglo, especificamos el nombre del arreglo y la posición del elemento dentro de éste encerrándola entre corchetes ([]). En C, el primer elemento de cualquier arreglo es el elemento cero; por lo tanto, el primer elemento del arreglo está en la posición 0, el segundo en la posición 1, ..., el i-ésimo elemento esta en la posición i-1.
Los arreglos ocupan espacio de memoria. El programador especifica el tipo de cada elemento y el número de elementos requerido por cada arreglo, de modo que el compilador reserve la memoria necesaria. Para declarar un arreglo, se utiliza la declaracióntipo nombre_del_arreglo[tamaño];
Los arreglos pueden tener múltiples dimensiones. Podemos usar un arreglo de dos dimensiones para representar: una matriz, una tabla, un tablero, etc. Un arreglo de múltiples dimensiones se declara de la siguiente formatipo nombre_del arreglo[tamaño1][tamaño2]...[tamañoN];
Es una buena práctica de programación declarar el tamaño del arreglo como una constante, en lugar de indicar el tamaño directamente en la declaración. Otra buena práctica de programación es reservar un poco más de espacio, del máximo esperado durante la ejecución del programa, esto nos puede evitar problemas de violación de segmento.
Por ejemplo si queremos usar un arreglo que almace 100 números flotantes, se utiliza la declaración#define SIZE 100 // usar una constante para definir el tamañofloat nums[SIZE+10]; // hacer el arreglo un poco más grande del máximo esperado
Para acceder a un elemento dentro del arreglo, se utiliza la declaraciónnums[2] = 5.0; // Asigna 5.0 al 3er elemento del arregloval = nums[2]; // Asigna el contenido del 3er elemento a la variable val
Ventajas y desventajas de usar arreglos:
Si conocemos la posición dentro del arreglo del elemento que queremos consultar, la consulta toma un tiempo constante.
Pueden ser usados para implementar otras estructuras de datos sofisticadas como pilas, colas, tablas hash. Su tamaño es fijo, por lo que si no se conoce de antemano el número máximo de elemento a almacenar pueden ocurrir problemas si el espacio reservado es menor del necesario.
Insertar elementos de manera ordenada es muy lento.
Buscar un elemento en un arreglo desordenado es muy lento.
Los arreglos son una colección de variables del mismo tipo que se referencian utilizando un nombre común. Un arreglo consta de posiciones de memoria contigua. La dirección más baja corresponde al primer elemento y la más alta al último. Un arreglo puede tener una o varias dimensiones. Para acceder a un elemento en particular de un arreglo se usa un índice.


7.1Arreglo Unidimensionales
El formato para declarar un arreglo unidimensional es:
tipo nombre_arr [ tamaño ]
Por ejemplo, para declarar un arreglo de enteros llamado listanum con diez elementos se hace de la siguiente forma:
int listanum[10];
En C, todos los arreglos usan cero como índice para el primer elemento. Por tanto, el ejemplo anterior declara un arreglo de enteros con diez elementos desde listanum[0] hasta listanum[9].
La forma como pueden ser accesados los elementos de un arreglo, es de la siguiente forma:
listanum[2] = 15; /* Asigna 15 al 3er elemento del arreglo listanum*/
num = listanum[2]; /* Asigna el contenido del 3er elemento a la variable num */
Un arreglo unidimensional es un tipo de datos estructurado que está formado de una colección finita y ordenada de datos del mismo tipo. Es la estructura natural para modelar listas de elementos iguales.
El tipo de acceso a los arreglos unidimensionales es el acceso directo, es decir, podemos acceder a cualquier elemento del arreglo sin tener que consultar a elementos anteriores o posteriores, esto mediante el uso de un índice para cada elemento del arreglo que nos da su posición relativa.
Para implementar arreglos unidimensionales se debe reservar espacio en memoria, y se debe proporcionar la dirección base del arreglo, la cota superior y la inferior.




REPRESENTACION EN MEMORIA
Los arreglos se representan en memoria de la forma siguiente: x : array[1..5] of integer
Para establecer el rango del arreglo (número total de elementos) que componen el arreglo se utiliza la siguiente formula: RANGO = Ls - (Li+1)
donde:
ls = Límite superior del arreglo
li = Límite inferior del arreglo
Para calcular la dirección de memoria de un elemento dentro de un arreglo se usa la siguiente formula: A[i] = base(A) + [(i-li) * w]
donde :
A = Identificador único del arreglo
i = Indice del elemento
li = Límite inferior
w = Número de bytes tipo componente
Si el arreglo en el cual estamos trabajando tiene un índice numerativo utilizaremos las siguientes fórmulas: RANGO = ord (ls) - (ord (li)+1) A[i] = base (A) + [ord (i) - ord (li) * w]

7.1.1 Conceptos básicos
Un arreglo unidimensional tiene una sola dimensión. En C#, la dimensión se maneja por medio de un par de corchetes.
A los arreglos de una dimensión también se les llama listas.

7.1.2 Operaciones Aplicaciones
Para manejar un arreglo, las operaciones a efectuarse son:
Declaración del arreglo,
Creación del arreglo,
Inicialización de de los elementos del arreglo, y
Acceso a los elementos del arreglo.
A continuación describiremos cada una de estas operaciones, en C#.
Declaración.
La declaración de un arreglo unidimensional consiste en establecer las características del arreglo y sus elementos, por medio de la siguiente sintaxis:
[ ] <> ;
Donde:
tipo indica el tipo correspondiente a los elementos del arreglo ,
identificador es el nombre del arreglo, y
el par de corchetes, [ ], representa la dimensión del arreglo y encierra un número entero que corresponde al número de elementos del arreglo.
Ejemplos:
int [ ] a ;
float [ ] distancia ;
Artículo [ ] art = new Artículo[ 3];
Observe que, en la declaración, el espacio entre los corchetes está vacío. Esto se debe a que, durante dicha operación, no se reserva espacio en la memoria.
Creación.
La creación de un arreglo unidimensional consiste en reservar espacio de memoria para todos sus elementos, utilizando la siguiente sintaxis:
<> = new [ tamaño ] ;
Donde:
new es el operador para gestionar espacio de memoria, en tiempo de ejecución,
tamaño es un número entero que representa el número de elementos del arreglo.
Ejemplos:
a = new int [10] ; // Se crea el arreglo a , con 10 elementos de tipo entero.
distancia = new float[ 5] ; // Se crea el arreglo distancia , con 5 elementos de punto flotante y precisión sencilla .Artículo [] art = new Artículo[3];
Artículo [ ] art = new Artículo[ 3]; // Se crean 3 referencias a objetos de la clase Artículo
art[0]= new Artículo(); // Se crea el primer objeto del arreglo art
art[1]= new Artículo(); // Se crea el segundo objeto del arreglo art
art[2]= new Artículo(); // Se crea el tercer objeto del arreglo art

Las dos primeras operaciones de declaración y creación anteriores se pueden agrupar en una sola instrucción, como se muestra enseguida:
int [ ] a = new int [10] ;
float [ ] distancia = new float[5] ;

Inicialización.
Un arreglo es un objeto que,cuando es creado por el compilador, se le asignan automáticamente valores iniciales predeterminados a cada uno de sus elementos, de acuerdo a los siguientes criterios:
Si el tipo del arreglo es numérico, a sus elementos se les asigna el valor cero.
Si el tipo del arreglo es char, a sus elementos se les asigna el valor '\u0000'.
Si el tipo del arreglo es bool, a sus elementos se les asigna el valor false.
Si el tipo del arreglo es una clase, a sus elementos se les asigna el valor null.
Cuando se requiere asignar valores iniciales diferentes de los predeterminados, es posible agrupar las operaciones de declaración, creación e inicialización en una sola instrucción, por ejemplo:
int [ ] a = { 1, 0,4,-6, 2,9, 23,455, 90,35 };
float [ ] distancia = { 2.50F, 286.45F, 46.75F, 30.62F, 93.00F };
string [ ] pato = { "Hugo", "Paco", "Luís" };

Acceso.
Se puede acceder a los valores de los elementos de un arreglo a través del nombre del arreglo y un subíndice. El subíndice debe escribirse entre corchetes y representa la posición del elemento en el arreglo. Así, podemos referirnos a un elemento del arreglo escribiendo el nombre del arreglo y el subíndice del elemento entre corchetes. Los valores de los subíndices empiezan en cero para el primer elemento, hasta el tamaño del arreglo menos uno.
Ejemplo:
float [ ] distancia = new float[5] ; // Crea el arreglo distancia con 5 elementos. float x = 25F, y = 10F ; // Crea dos variables de punto flotante y precisión sencilla. distancia[0] = x + y ; // El valor asignado al primer elemento es 35. distancia[1] = ++distancia[0] ; // Asigna 36 al segundo elemento. distancia[2] = distancia[1] - distancia[0] + 4 ; // Asigna 5 al tercer elemento. distancia[3] = distancia[2]-- ; // Asigna 5 al cuarto elemento
// y disminuye en 1 el valor del tercero.
distancia[4] = distancia[3] * distancia[2] ; // Asigna 20 al quinto elemento. y = distancia[4] ; // Asigna a y el valor almacenado en el quinto elemento.
1.1.3.- Aplicaciones.
Listas.
Resolvamos el problema de manejar dos listas: una con los nombres de un grupo de alumnos y otra con una calificación para cada uno de los alumnos. Primero se deberán leer los nombres de los alumnos y la calificación que corresponde a cada uno de ellos y después habrá que desplegar dos columnas: una con los nombres de los alumnos y la otra con sus respectivas calificaciones.
La lectura debe lucir de manera similar a la siguiente:
Número de alumnos: 30
Nombre [0] : Calificación[0] :
Nombre [1] : Calificación[1] :
Nombre [2] : Calificación[2] :
......
Nombre [29] : Calificación[29] :
El despliegue en el monitor luciría así:
No.
Nombre
Calif.
1
Hugo
100
2
Paco
90
3
Luís
95
...

...
30
Donald
70
El siguiente código corresponde a un programa que resuelve el problema.
// Lista.cs : Lee una lista de nombres y calificaciones correspondientes a un grupo de
// alumnos de una materia.
using System;using C = System.Console;
public class Lista{
public static void Main()
{
int nAlumnos;
C.Write("Número de alumnos: ");
nAlumnos = Convert.ToInt32(C.ReadLine());
string [ ] alumnos = new string[nAlumnos]; //Crea el arreglo de
//alumnos.
int [ ] calif = new int [nAlumnos]; // Crea el arreglo de calificaciones.
// Lee los elementos de los dos arreglos.
for(int i = 0; i < i =" 0">[ , ] <> ;
Donde:
tipo indica el tipo correspondiente a los elementos del arreglo ,
identificador es el nombre del arreglo, y
el par de corchetes y la coma, [ , ], representan las dimensiones del arreglo y encierra dos números enteros, cuyo producto corresponde al número de elementos del arreglo.
Ejemplos:
double [ , ] matriz ;
int [ , ] ubicación ;
Rama [ , ] árbol; // Rama es una clase.
Observe que, en la declaración, el espacio entre los corchetes está vacío. Esto se debe a que, durante dicha operación, no se reserva espacio en la memoria.
Creación.
La creación de un arreglo bidimensional consiste en reservar espacio en la memoria para todos sus elementos, utilizando la siguiente sintaxis:
<> = new [ dim1, dim2 ] ;
Donde:
new es el operador para gestionar espacio de memoria, en tiempo de ejecución,
dim1 y dim2 son valores enteros que representan las dimensioes del arreglo.
El tamaño del arreglo es el resultado de multiplicar los valores de las dimensiones y representa el número de elementos del arreglo.
Ejemplos:
matriz = new double [2, 3] ; // Se crea el arreglo matriz, con 6 elementos de tipo
//punto flotante y precición doble .
ubicación = new int[ 4,2] ; // Se crea el arreglo ubicación, con 8 elementos de
//tipo entero de 32 bits .
árbol = new Rama[5,2] ; // Se crea el arreglo arbol, con 10 objetos
//de la clase Rama.
Las operaciones de declaración y creación anteriores se pueden agrupar en una sola instrucción, como se muestra enseguida:
double [ , ] matriz = new double [2,3] ;
int [ , ] ubicación = new int[4, 2] ;
Rama [ , ] alumno = new Rama[5,2] ;

Inicialización.
Un arreglo es un objeto que,cuando es creado por el compilador, se le asignan automáticamente valores iniciales predeterminados a cada uno de sus elementos, de acuerdo a los siguientes criterios:
Si el tipo del arreglo es numérico, a sus elementos se les asigna el valor cero.
Si el tipo del arreglo es char, a sus elementos se les asigna el valor '\u0000'.
Si el tipo del arreglo es bool, a sus elementos se les asigna el valor false.
Si el tipo del arreglo es una clase, a sus elementos se les asigna el valor null.
Cuando se requiere asignar valores iniciales diferentes de los predeterminados, es posible agrupar las operaciones de declaración, creación e inicialización en una sola instrucción, por ejemplo:

double [ , ] matriz = { {1.5, 0, 4, -6.5, 2 } , {2.3, 9, 3.5, 4.8, 6.2} };
int [ , ] ubicación = { {2, 4} , {6, 8} , {9, 10}, {5 , 1}};
string [ , ] funcionario = { {"Hugo", "jefe"} ,
{ "Paco", "operador "},
{ "Luís","ayudante"} };

Acceso.
Se puede acceder a los valores de los elementos de un arreglo bidimensional a través del nombre del arreglo y dos subíndices. Los subíndices deben escribirse entre corchetes y representa la posición del elemento en el arreglo. Así, podemos referirnos a un elemento del arreglo escribiendo el nombre del arreglo y los subíndices del elemento entre corchetes. Los valores de los subíndices empiezan en cero para el primer elemento, hasta el tamaño del arreglo menos uno.
Ejemplo:
int [ , ] posición = new int[5, 10] ; // Crea el arreglo posición , con 50 elementos de tipo entero.
int x;posición[ 3, 5] = 3 ;
x = posición[ 3, 5] ;
1.2.3.- Aplicaciones.
Matrices.
Una matriz es un arreglo rectangular de dos dimensiones, donde el acomodo de los elementos está dispuesto en renglones y columnas.
Ejemplo 1:
Se debe controlar la ubicación de los asistentes a una sala de conferencias por medio de un gafete que tiene escrito el nombre del asistente, la fila y la columna donde se ubica su asiento.
El siguiente segmento de código muestra la solución con arreglos bidimensionales.
string [ , ] asistente = new string[10,12] ;
// Inicializa los valores de los nombres con cadenas vacías.
for(int i=0 ; i < 10 ; i++ ) // Controla la fila.
for(int j=0 ; j < 12 ; j++ ) // Controla la columna.
asistente[ i , j ] = " " ;
// Captura los nombres de todos los asistentes y les asigna sus asientos,
// en el orden en que van llegando.
for(int i=0 ; i < 10 ; i++ ) // Controla la fila.
for(int j=0 ; j < 12 ; j++ ) // Controla la columna.
asistente[ i , j ] = System.Console.ReadLine( );
// Despliega los nombres de todos los asistentes.
for(int i=0 ; i < 10 ; i++ ) // Controla la fila.
for(int j=0 ; j < 12 ; j++ ) // Controla la columna.
System.Console.WriteLine( asistente[ i , j ] );