Introducción a la programación y la informática. Tema 10

60
Tema 10. Arrays: definición y aplicaciones Introducción a la Informática y a la Programación (IIP) Curso 2011/12 Departamento de Sistemas Informáticos y Computación

Transcript of Introducción a la programación y la informática. Tema 10

Page 1: Introducción a la programación y la informática. Tema 10

Tema 10. Arrays: definición y aplicaciones

Introducción a la Informática y a la Programación (IIP)

Curso 2011/12

Departamento de Sistemas Informáticos y Computación

Page 2: Introducción a la programación y la informática. Tema 10

Contenidos

1. Arrays unidimensionales

2. Tratamiento secuencial y directo de un array

3. Representación de una secuencia de datos dinámica usando un array

4. Arrays multidimensionales

5. Más problemas de acceso directo

6. Problemas propuestos

25/11/2011 IIP - Curso 2011/12 2

Page 3: Introducción a la programación y la informática. Tema 10

Introducción

• A menudo interesa almacenar y referenciar variables que representan una colección de valores, para poder tratarlos de forma uniforme.

• Ejemplos: – Obtener estadísticas básicas sobre medidas diarias de la temperatura

media en una determinada zona geográfica.

– Manejar una colección de objetos homogéneos, por ejemplo, una clase Garaje que pueda tener asociado un conjunto de objetos de tipo Vehiculo.

– …

• Java proporciona el array como mecanismo para agrupar datos de tipo homogéneo (tanto de tipo objeto como de tipo primitivo).

25/11/2011 IIP - Curso 2011/12 3

Page 4: Introducción a la programación y la informática. Tema 10

Arrays unidimensionales

• Definición: Un array es una colección de elementos homogéneos (del mismo tipo de datos) agrupados de forma consecutiva en memoria.

• Características – Cada elemento de un array tiene asociado un índice, que es un

número entero no negativo que lo identifica inequívocamente y permite acceder a él.

– El tamaño (número de componentes) del array debe establecerse en su declaración y es invariable a lo largo de la ejecución.

– El acceso a los elementos de un array es directo (gracias a su índice).

• Estas estructuras de datos son adecuadas para situaciones en las que el acceso a los datos se realice de forma aleatoria (esto es, conjuntos de datos que pueden ser indexados) o secuencial.

25/11/2011 IIP - Curso 2011/12 4

Page 5: Introducción a la programación y la informática. Tema 10

• Valores: Se representan como una sucesión de elementos entre llaves y separados por comas.

{e0, e1, … ,en-1}

• Operador de arrays: Operador de acceso a las componentes []

nomVble[índice]

índice es una expresión que se evalúa a un valor válido para el array nomVble.

• Declaración y creación:

– Declaración: tipo[] nomVble; ó tipo nomVble[];

– Inicialización (con componentes): nomVble = new tipo[tamaño];

– Conjuntamente: tipo[] nomVble = new tipo[tamaño];

tipo es cualquier tipo primitivo o referencia, nomVble es cualquier identificador válido y tamaño es una expresión que se evalúa a un entero no negativo y determina la cantidad de componentes.

25/11/2011 IIP - Curso 2011/12 5

Arrays unidimensionales Declaración y uso

Válido pero desaconsejado

Page 6: Introducción a la programación y la informática. Tema 10

• Todos los arrays disponen de un atributo constante (de sólo consulta) length que indica la cantidad de componentes (tamaño) de un array:

nomVble.length

• Los índices válidos de un array van desde 0 hasta length-1.

• Una variable array puede verse como una referencia a la posición de memoria del primer elemento del array.

• Existe una referencia especial que puede utilizarse con cualquier array (o con otros tipos referencia): null.

• Todas las componentes de arrays de tipo numérico se inicializan por defecto a 0.

• Todas las componentes de arrays de tipo referencia (p.e., un array de String) se inicializan por defecto a null.

25/11/2011 IIP - Curso 2011/12 6

Arrays unidimensionales Declaración y uso

Page 7: Introducción a la programación y la informática. Tema 10

• Gráficamente podemos ver un array como sigue:

25/11/2011 IIP - Curso 2011/12 7

Arrays unidimensionales Declaración y uso

e0 e1 e2 e3 en-1

0 1 2 3 … nomVble.length-1

nomVble

donde n = nomVble.length y todos los ei , 0≤i<n, son del mismo tipo.

Variable referencia Componentes

Valores

Índice Tamaño

Último índice

Page 8: Introducción a la programación y la informática. Tema 10

• Array de 5 caracteres:

– Variable referencia: char[] letras;

– Objeto array (con componentes): letras = new char[5];

– Conjuntamente: char[] letras = new char[5];

• Dos arrays de enteros:

int[] numeros1 = new int[5000], numeros2 = new int[50];

• Array de 20 cadenas de caracteres: final int NUM = 10;

String[] nombres = new String[NUM*2];

• Array de reales cuya cantidad de componentes se decide por teclado:

double[] precios = new double[teclado.nextInt()];

• Creación e inicialización de un array de 4 enteros: int[] v={-5,6,10,3};

25/11/2011 IIP - Curso 2011/12 8

‘V’ ‘g’ ‘A’ ‘i’ ‘J’ letras

0 1 2 3 4 = letras.length-1

Arrays unidimensionales Declaración y uso - Ejemplos

Page 9: Introducción a la programación y la informática. Tema 10

• En un array de tamaño N, los índices válidos para acceder a sus componentes pertenecen al intervalo [0, N−1].

• Un acceso fuera de dicho intervalo producirá una excepción en ejecución del tipo:

java.lang.ArrayIndexOutOfBoundsException

• Por ejemplo:

int[] n = new int[10];

int a = n[11]; // Produce una excepción

a = n[-1]; // Produce una excepción

• El acceso a las componentes de un array debe controlarse utilizando las cotas inferior (0) y superior (nomVble.length-1) de los índices.

25/11/2011 IIP - Curso 2011/12 9

Arrays - Excepciones

Page 10: Introducción a la programación y la informática. Tema 10

• Una variable referencia array (nomVble) utiliza la memoria donde haya sido definida.

• Las componentes del array se crean en el montículo o heap que es una zona de memoria reservada para guardar variables dinámicas.

• Las variables dinámicas son variables que se crean en tiempo de ejecución mediante la operación de creación new.

• Las componentes sólo son accesibles si existe una referencia a ellas.

• Es posible sugerir la destrucción de un array v al desreferenciarlo (v = null)

– Recuerda que existe un mecanismo de recolección de basura (garbage collector) que se activa automáticamente en tiempo de ejecución y libera la memoria que está ocupada pero no es accesible al no estar referenciada.

– También se puede sugerir su ejecución mediante la instrucción System.gc().

25/11/2011 IIP - Curso 2011/12 10

Arrays - Memoria

Page 11: Introducción a la programación y la informática. Tema 10

• Las componentes de un array pueden verse como variables del tipo de los elementos del array.

nomVble[índice] = expresión;

expresión debe ser del tipo de las componentes del array nomVble. • La asignación entre arrays sólo afecta a las referencias.

int[] v1 = {1,3,2,0}; int[] v2; v2 = v1; boolean igual = (v1==v2); // igual vale true

• Si se desea una copia de un array se deben crear nuevas componentes y realizar la asignación de cada uno de los valores.

v2 = new int[4]; v2[0]=v1[0]; v2[1]=v1[1]; v2[2]=v1[2]; v2[3]=v1[3]; igual = (v1==v2); // igual vale false

25/11/2011 IIP - Curso 2011/12 11

1 3 2 0

v1

v2 0 1 2 3

1 3 2 0 v1

v2 0 1 2 3

1 3 2 0 0 1 2 3

Arrays unidimensionales - Asignación

Page 12: Introducción a la programación y la informática. Tema 10

• Los arrays se definen como cualquier parámetro formal, indicando el tipo y el nombre de la variable

static int metodo1(int[] v1, int[] v2) { … }

public static void main(String[] args) { … }

• En la llamada, sólo se utiliza el nombre de la variable: int i = metodo1(a1,a2);

• Cuando se invoca a un método con algún argumento de tipo referencia sólo se copia la referencia del parámetro real en el formal.

• Los métodos pueden devolver como resultado un array (referencia a las componentes). Por ejemplo:

static char[] metodo2(int[] v1) { char[] nuevo = new char[v1.length+10]; … return nuevo; }

25/11/2011 IIP - Curso 2011/12 12

Arrays unidimensionales - Métodos

Page 13: Introducción a la programación y la informática. Tema 10

Ejemplo: Paso de arrays como parámetros

25/11/2011 IIP - Curso 2011/12 13

public class PasoParametros {

public static void main(String[] args) {

double[] elArray = {5.0, 6.4, 3.2, 0.0, 1.2};

metodo1(elArray);

// el array no ha sido modificado en absoluto

metodo2(elArray);

// la primera componente del array vale ahora 0.1

}

public static void metodo1(double[] copia) {

copia = new double[5]; // Este array desaparece al acabar el método

}

public static void metodo2(double[] copia) {

copia[0] = 0.1;

}

}

Page 14: Introducción a la programación y la informática. Tema 10

Arrays de objetos • Es posible construir arrays de objetos.

• Las componentes del array valdrán inicialmente null.

25/11/2011 IIP - Curso 2011/12 14

class Estudiante { private long dni; private double nota; private String nombre; private boolean asistencia; ... }

public static void main(String[] args) { Estudiante grupo[] = new Estudiante[56]; grupo[0] = new Estudiante(); grupo[0].setDni(12123123); grupo[0].setNota(8.5); grupo[0].setNombre(“Luisa García”); grupo[0].setAsistencia(true); }

Page 15: Introducción a la programación y la informática. Tema 10

• Gráficamente:

25/11/2011 IIP - Curso 2011/12 15

Arrays de objetos

null null null null

0 1 2 3 … 55 grupo.length-1

grupo

dni

nota

nombre

asistencia

12123123

8.5 true

“Luisa García”

grupo[0]

Estudiante

Page 16: Introducción a la programación y la informática. Tema 10

Array de objetos - Ejemplo

• Se asume que la clase Punto implementa el método distancia.

25/11/2011 IIP - Curso 2011/12 16

public class TestArrayObjetos { public static final int NUM_PUNTOS = 20; public static void main(String[] args) { Punto[] camino = new Punto[NUM_PUNTOS]; for(int i=0; i<camino.length; i++) camino[i] = new Punto(); // se han creado los 20 objetos Punto de camino ... System.out.println("Distancia entre los dos primeros puntos: " + camino[0].distancia(camino[1])); Punto[] copiaP = copiarPunto(camino); } public static Punto[] copiarPunto(Punto[] orig) { Punto[] copia = new Punto[orig.length]; for (int i=0; i<orig.length; i++) copia[i] = new Punto(orig[i].getX(),orig[i].getY()); return copia; } }

Page 17: Introducción a la programación y la informática. Tema 10

Tratamiento secuencial y directo de un array

25/11/2011 IIP - Curs 2011/12 17

• Por lo general se consideran dos tipos de tratamiento de los elementos

de una estructura lineal: los denominados tratamiento directo y secuencial:

– Directo: Se accede a los elementos por su posición, sin ningún patrón de acceso

específico. • Ejemplos de acceso por posición: Problemas que usan la estructura como un conjunto

de contadores o como referencias posicionales, • Ejemplos más complejos: Problemas que aprovechan el acceso directo de los arrays y las

propiedades de ordenación de sus elementos como la búsqueda binaria o los algoritmos de ordenación, etc. (Se verán más adelante)

– Secuencial: Se accede a los elementos de la estructura (o de una parte de ella) posicionalmente, uno detrás del otro. • Ejemplos: Problemas de recorrido y búsqueda secuencial.

• Como los arrays son estructuras de acceso directo, cualquiera de los

dos tipos de tratamiento es posible.

Page 18: Introducción a la programación y la informática. Tema 10

Acceso directo I: array de contadores Supongamos que queremos contar los números las veces que un usuario escribe números del 0 al 9. Una solución inadecuada, sería definir 10 variables contador1, contador2, ... contador10 y una estructura de switch o de if anidados para incrementar el contador correcto en cada caso. La solución ideal, sería usar un array de contadores:

25/11/2011 IIP - Curso 2011/12 18

import java.util.Scanner;

public class EjemploContadores {

public static void main(String[] args) {

Scanner tec = new Scanner(System.in);

int[] contadores = new int[10]; boolean salir = false;

do{ val=tec.nextInt();

if (val>=0 && val<=9) contadores[val]++;

else salir=true;

}while(!salir);

}

}

Page 19: Introducción a la programación y la informática. Tema 10

Acceso secuencial: recorrido y búsqueda

• Un recorrido se caracteriza por tener que visitar todos los elementos del array para poder encontrar la solución del problema.

– Por el contrario, una búsqueda persigue encontrar el primero elemento que cumple una característica dada.

• El recorrido de arrays se utiliza para resolver problemas que precisan procesar todos los datos para poder determinar la solución.

• Ejemplos:

– Obtener el máximo o el mínimo de un conjunto de números, obtener la suma o el producto de todos los números de un conjunto dado, obtener la media, etc.

• Se llevan a cabo mediante variables enteras que se usan como índices para acceder a sus distintas posiciones.

• Se debe llevar el control de qué posiciones ya se han visitado y cuántas se deben visitar para poder solucionar el problema.

25/11/2011 IIP - Curso 2011/12 19

Page 20: Introducción a la programación y la informática. Tema 10

Recorrido ascendente de un array

• Recorrido iterativo ascendente con un bucle while:

• Recorrido iterativo ascendente con un bucle for:

• El método avanzar representa el incremento del índice.

25/11/2011 IIP - Curso 2011/12 20

int i=inicio; while (i<=fin) { tratar(a[i]); // Operaciones con elemento i-ésimo avanzar(i); }

for (int i=inicio; i<=fin; avanzar(i)) { tratar(a[i]); // Operaciones con elemento i-ésimo }

Page 21: Introducción a la programación y la informática. Tema 10

Recorrido descendente de un array

• Recorrido iterativo descendente con un bucle while:

• Recorrido iterativo descendente con un bucle for:

• El método retroceder representa el decremento del índice.

25/11/2011 IIP - Curso 2011/12 21

int i=fin; while (i>=inicio) { tratar(a[i]); // Operaciones con elemento i-ésimo retroceder(i); }

for (int i=fin; i>=inicio; retroceder(i)) { tratar(a[i]); // Operaciones con elemento i-ésimo }

Page 22: Introducción a la programación y la informática. Tema 10

Problemas de recorrido en arrays

• Ejemplo de recorrido iterativo ascendente: método que suma todos los elementos de un array de enteros.

25/11/2011 IIP - Curso 2011/12 22

Y si queremos calcular la media de los

elementos del array?

static double mediaIteAsc(int[] v) { double suma=0; for (int i=0; i<v.length; i++) suma = suma + v[i]; return suma/v.length; }

0 1 2 3 4 5

v

v.length = 6

static int sumaIteAsc(int[] v) { int suma=0; for (int i=0; i<v.length; i++) suma = suma + v[i]; return suma; }

Page 23: Introducción a la programación y la informática. Tema 10

Problemas de recorrido en arrays

• Ejemplo de procesado de parte de un array: método que calcula la media aritmética del subarray a[izq … der]

• El número de elementos entre izq y der (izq<=der) es: der-izq+1

25/11/2011 IIP - Curso 2011/12 23

public static double media(int[] a, int izq, int der){ double suma = 0; for (int i=izq; i<=der; i++) suma+=a[i]; return suma/(der-izq+1); }

0 1 2 3 4 5

v

6

Hay 4 elementos en v[2…5] (5-2+1)

Page 24: Introducción a la programación y la informática. Tema 10

Problemas de recorrido en arrays

• Ejemplo de recorrido iterativo descendente: método que suma todos los elementos de un array de enteros.

• El bucle se detiene cuando i < 0, es decir, tras procesar la componente 0 del array, cuando i vale -1.

25/11/2011 IIP - Curso 2011/12 24

0 1 2 3 4 5

v v.length = 6

public static int sumaIteDesc(int[] v) { int suma=0; for (int i=v.length-1; i>=0; i--) suma = suma + v[i]; return suma; }

Page 25: Introducción a la programación y la informática. Tema 10

Problemas de recorrido en arrays

• Ejemplo de recorrido iterativo ascendente: Calcula la posición del máximo en el array a.

• Fíjate que el recorrido se inicia en 1, ya que la posición 0 ya ha sido tratada.

• Recuerda que los tipos primitivos se comparan con ==,>,>=,<,<= mientras que los tipos objeto se comparan con los métodos equals y/o compareTo.

25/11/2011 IIP - Curso 2011/12 25

public static int maximo(String[] a) { int posMax = 0; for (int i=1; i<a.length; i++) if (a[i].compareTo(a[posMax])>0) posMax = i; return posMax; }

Page 26: Introducción a la programación y la informática. Tema 10

Problemas de recorrido en arrays

• Ejemplo de recorrido iterativo descendente: Calcula la posición del máximo en el array a.

• El recorrido se inicia en a.length-2, ya que la posición a.length-1 ya ha sido tratada.

25/11/2011 IIP - Curso 2011/12 26

public static int maximo(double[] a) { int posMax = a.length-1; for (int i=a.length-2; i>=0; i--) if (a[i]>a[posMax]) posMax = i; return posMax; }

Page 27: Introducción a la programación y la informática. Tema 10

Esquemas de búsqueda en arrays

• Una búsqueda requiere determinar si existe algún elemento del array que cumpla una cierta propiedad.

• Este tipo de problemas implican operaciones que pueden obtener la solución sin necesidad de conocer todos los datos: localizar el primero que cumpla cierto requisito, tratar todos los datos hasta que se cumpla cierta condición, etc. – Las búsquedas en arrays requieren el uso de variables de tipo int para

acceder a sus distintas posiciones, de forma similar a los recorridos, y con variables de tipo boolean para comprobar la condición de terminación.

– Debemos llevar el control de que posiciones ya se han visitado y cuantas se deben visitar para poder solucionar el problema.

25/11/2011 IIP - Curso 2011/12 27

Page 28: Introducción a la programación y la informática. Tema 10

Problemas de búsqueda en arrays

• Se establecen dos estrategias principales a la hora de buscar:

– Búsqueda lineal: se va reduciendo la cantidad de información sobre la que buscar elemento a elemento. Se puede aplicar siempre independientemente de si los datos están ordenados o no en el array.

– Búsqueda binaria o dicotómica: se va reduciendo la cantidad de información sobre la que buscar, eliminando cada vez la mitad de elementos. Esta estrategia necesita que los datos dentro del array estén ordenados de una forma conocida (por ejemplo, de menor a mayor), pero es más eficiente que las búsquedas lineales.

25/11/2011 IIP - Curso 2011/12 28

Page 29: Introducción a la programación y la informática. Tema 10

Búsqueda ascendente en un array

• Estructura de búsqueda ascendente utilizando una variable lógica: ¿Existe algún elemento a[i] que cumpla la propiedad?

25/11/2011 IIP - Curso 2011/12 29

int i=inicio, j=fin; boolean encontrado=false; while (i<=j && !encontrado) { if (propiedad(a[i])) encontrado=true; else avanzar(i); } // Resolver la búsqueda if (encontrado) ... // a[i] cumple la propiedad else ... // ningún elemento cumple la propiedad

Page 30: Introducción a la programación y la informática. Tema 10

Búsqueda descendente en un array

• Estructura de búsqueda descendente utilizando una variable lógica: ¿Existe algún elemento a[i] que cumpla la propiedad?

25/11/2011 IIP - Curso 2011/12 30

int i=inicio, j=fin; boolean encontrado=false; while (j>=i && !encontrado) { if (propiedad(a[j])) encontrado=true; else retroceder(j); } // Resolver la búsqueda if (encontrado) ... // a[j] cumple la propiedad else ... // ningún elemento cumple la propiedad

Page 31: Introducción a la programación y la informática. Tema 10

Estrategias de búsqueda en arrays

• Estructura de búsqueda ascendente. Solución con salida del bucle, acabando el método en ejecución.

25/11/2011 IIP - Curso 2011/12 31

int i=inicio, j=fin; while (i<=j) { if (propiedad(a[i])) return i; //Búsqueda con éxito avanzar(i); } // i>j y ningún elemento cumple la propiedad return -1;

Page 32: Introducción a la programación y la informática. Tema 10

Estrategias de búsqueda en arrays

• Estructura de búsqueda ascendente con garantía de éxito: se sabe de antemano que existe algún elemento a[i] que cumple la propiedad.

• Es posible incluir deliberadamente un elemento que cumpla la propiedad. Dicho elemento se denomina centinela. En ese caso, la búsqueda se llama búsqueda con centinela.

25/11/2011 IIP - Curso 2011/12 32

int i=inicio; while (!propiedad(a[i])) avanzar(i); // Resolver la búsqueda: Se sabe que en i // hay un elemento que cumple la propiedad

Page 33: Introducción a la programación y la informática. Tema 10

Estrategias de búsqueda en arrays

• Estructura de búsqueda lineal iterativa (sin garantía de éxito) con guarda que evalúa la propiedad. ¿Algún elemento a[i] cumple la propiedad?

25/11/2011 IIP - Curso 2011/12 33

int i=inicio, j=fin; While (i<=j && !propiedad(a[i])) avanzar(i); // El bucle acaba porque: // i <= fin a[i] cumple la propiedad o // i vale fin+1 // Resolver la búsqueda if (i<=fin) ... // se cumple propiedad(a[i]) else ... // no hay ningún elemento a[i] // que cumpla propiedad(a[i])

Page 34: Introducción a la programación y la informática. Tema 10

Problemas de búsqueda sobre arrays • Búsqueda ascendente de un elemento en un array de String sin

garantía de éxito. Si no lo encuentra, devuelve -1.

25/11/2011 IIP - Curso 2011/12 34

public static int buscarPos(String[] a, String dato) {

int i = 0;

while (i<a.length && !a[i].equals(dato)) i++;

if (i<a.length) return i;

else return -1; // o bien directamente: return -1;

}

• Búsqueda descendente de un elemento en un array de double sin garantía de éxito. Si no lo encuentra, devuelve -1.

public static int buscarPos(double[] a, double dato) {

int i = a.length-1;

while (i>=0 && a[i]!=dato) i--;

return i;

}

Page 35: Introducción a la programación y la informática. Tema 10

Problemas de búsqueda sobre arrays • Búsqueda ascendente de un elemento en un array de String

con garantía de éxito.

25/11/2011 IIP - Curso 2011/12 35

public static int buscarPosEsta(String[] a, String dato) {

int i = 0;

while (!a[i].equals(dato)) i++;

return i;

}

• Búsqueda descendente de un elemento en un array de double con garantía de éxito.

public static int buscarPosEsta(double[] a, double dato) {

int i = a.length-1;

while (a[i]!=dato) i--;

return i;

}

Page 36: Introducción a la programación y la informática. Tema 10

Problemas de búsqueda sobre arrays • Comprueba si hay algún elemento del array mayor que dato.

• Devuelve, si existe, la posición del primer elemento del array mayor que la suma de los anteriores. Si no, devuelve -1.

25/11/2011 IIP - Curso 2011/12 36

public static boolean estaMayor(double[] a, double dato) {

int i = 0;

while (i<a.length && a[i]<=dato) i++;

return (i<a.length);

}

public static int buscaPosMaySuma(int[] a, int dato) {

int i = 0, suma = 0;

while (i<a.length && a[i]<=suma) { suma+=a[i]; i++; }

if (i<a.length) return i;

else return -1;

}

Page 37: Introducción a la programación y la informática. Tema 10

Esquemas combinados de búsqueda y recorrido sobre arrays

• Hay problemas que requieren combinar ambas estrategias. Ej.: – Dado un array de String, determinar para cada String del array la

primera repetición. El resultado debe ser un String en el que en cada línea conste el dato y las dos posiciones en las que aparece.

25/11/2011 IIP - Curso 2011/12 37

public static String listaDuplicados(String[] a) {

String res = "";

for (int i=0; i<a.length; i++) {

int j = i+1;

while (j<a.length && !a[i].equals(a[j])) j++;

if (j<a.length)

res+=a[i] + " duplicado en: " + i + " y " + j + "\n";

}

return res;

}

Page 38: Introducción a la programación y la informática. Tema 10

Representación de una secuencia de datos dinámica usando un array (I)

• Un array permite la representación sencilla de una lista de datos en la que se puede añadir y eliminar elementos.

• Elementos en posiciones consecutivas del array: [0,numElem-1] – Primera posición libre en numElem

• Se construye un array de tamaño igual al número máximo de elementos a almacenar.

tipoBase[] lista = new tipoBase[MAX_ELEM]; int numElem = 0;

25/11/2011 IIP - Curso 2011/12 38

lista 0 11

elementos de la lista numElem = 7

6 posiciones vacías

Page 39: Introducción a la programación y la informática. Tema 10

Representación de una secuencia de datos dinámica usando un array (II)

• Para añadir un nuevo elemento a la lista:

• Borrar un elemento de la lista debe preservar la contigüidad de los elementos y su orden de inserción.

– Desplazar los elementos posteriores una posición a la izquierda.

25/11/2011 IIP - Curso 2011/12 39

int i = 0; while (i<numElem && lista[i] distinto de x) i++; if (i<numElem) { for (int j=i+1; j<numElem; j++) lista[j-1] = lista[j]; numElem--; } else // búsqueda sin éxito

if (numElem<MAX_ELEM) lista[numElem++] = x; else // tratar el caso de lista llena

Page 40: Introducción a la programación y la informática. Tema 10

Arrays multidimensionales: Justificación

• Ejemplo de aplicación: – Medidas de temperatura en una zona para todos los días de un año.

• Soluciones posibles: – Array temp de 366 elementos (por si el año es bisiesto) que almacena de

forma correlativa los datos de temperatura para cada día.

• 1 de Enero temp[0] 3 de Febrero temp[33] 2 de Julio temp[183]

– Representación matricial de dimensiones 12x31

• Simplifica los cálculos de la posición real de cada día en la estructura de datos.

25/11/2011 IIP - Curso 2011/12 40

… …

… 0

11

12

fila

s

31 columnas

0 30 Esta representación

desperdicia memoria

Page 41: Introducción a la programación y la informática. Tema 10

Arrays multidimensionales: Justificación (II)

– Representación mediante array multidimensional con 12 filas y tamaño variable de columnas:

• Siempre es conveniente ajustar el tamaño del array a los datos que se vayan a almacenar para reducir el consumo de memoria. – Se trata de un array de 12 componentes donde cada componente es a su

vez un array con un nº variable de componentes. Esto es un ejemplo de array multidimensional (array de arrays).

25/11/2011 IIP - Curso 2011/12 41

… …

… 0

11

12

fila

s

0 30 29 Enero tiene 31 días

Febrero puede tener 28 ó 29 días

Marzo puede tener 31 días

Diciembre puede tener 31 días

Esta representación reduce el consumo

de memoria

nº variable de columnas

Page 42: Introducción a la programación y la informática. Tema 10

Arrays multidimensionales: Definición

• Definición: Un array multidimensional es un array cuyas componentes son a su vez arrays.

• La dimensión de un array es el número de definiciones anidadas que incluye.

• Cada anidamiento es un array de una dimensión menor.

• La dimensión define el número de índices que se utilizarán para acceder a los elementos primitivos del array.

25/11/2011 IIP - Curso 2011/12 42

Page 43: Introducción a la programación y la informática. Tema 10

Arrays multidimensionales Declaración y uso

• Valores: Se representan como una sucesión de elementos entre llaves y separados por comas. Por ejemplo: {{1,2},{1,2,3},{1}} es un array bidimensional de enteros con tres arrays unidimensionales.

• Operador: El operador de acceso [] debe repetirse para cada dimensión. nomVble[índice1][índice2]…[índiceN]

índicek es una expresión que se evalúa a un índice válido para el array nomVble en la dimensión k

• Declaración y creación: – Declaración: deben de aparecer tantos pares de corchetes como la dimensión del

array. tipo[]…[] nomVble; – Inicialización: deben de aparecer tantos pares de corchetes como la dimensión

del array y, al menos, la primera dimensión debe de tener un tamaño específico. Las demás dimensiones pueden estar vacías.

nomVble = new tipo[expresión1]…[expresiónN]; ̶ Conjuntamente: tipo[]…[] nomVble = new tipo[expresión1]…[expresiónN];

25/11/2011 IIP - Curso 2011/12 43

Page 44: Introducción a la programación y la informática. Tema 10

int[][] v;

v = new int[5][];

v[0] = new int[3];

v[1] = new int[2];

v[3] = new int[3];

v[4] = new int[1];

v[0][1] = 10;

v[4][0] = 3;

Errores:

v[2] = -3; //Error de compilación

v[4][1] = -3; // Error en ejecución

// ArrayIndexOutOfBoundsException

Arrays bidimensionales

25/11/2011 IIP - Curso 2011/12 44

10

(null)

3

0

1

2

3

4

v

0 1 2

v[3]

v[3][1]

v[v.length-1]

0

v[v.length-1][v[v.length-1].length-1] v[3][v[3].length-1]

v[0]

v[0][1]

0 1 2

v[0][2]

Page 45: Introducción a la programación y la informática. Tema 10

• Las matrices son un caso particular de arrays bidimensionales donde todos los arrays de la segunda dimensión tienen el mismo tamaño.

• Se pueden definir con una única instrucción new.

• Ejemplo: matriz con dos filas y tres columnas:

double[][] matriz = new double[2][3];

• Otra forma:

double[][] matriz = new double[2][];

matriz[0] = new double[3];

matriz[1] = new double[3];

Arrays bidimensionales: Matrices

25/11/2011 IIP - Curso 2011/12 45

0

1

matriz

0 1 2

0 1 2 for(int i=0; i<matriz.length; i++) for(int j=0; j<matriz[i].length; j++) matriz[i][j] = teclado.nextDouble();

Page 46: Introducción a la programación y la informática. Tema 10

Arrays Multidimensionales Ejemplo: Temperatura (I)

• Declaración de una matriz de 12x31 para almacenar las medidas diarias de temperatura para cada mes.

• Declaración de un array multidimensional de 12 filas y nº variable de columnas.

25/11/2011 IIP - Curso 2011/12 46

double[][] tempMed = new double[12][31];

tempMed[3][6] = 50.1; // Temp. del día 7 de Abril

double[][] tempMed = new double[12][];

// tempMed.length es igual a 12

tempMed[0] = new double[31]; // Índices del 0 al 30

tempMed[1] = new double[29]; // Índices del 0 al 28

// …

tempMed[2][4] = 78.0; // Temp. del día 5 de Marzo

Page 47: Introducción a la programación y la informática. Tema 10

Arrays Multidimensionales Ejemplo: Temperatura (II)

• Alternativa de implementación con definición previa del nº de días.

• tempMed[i][j] representa la temperatura media del día (j+1) del mes (i+1) – tempMed[3][14] es la temperatura media del 15 de Abril

25/11/2011 IIP - Curso 2011/12 47

final int[] NUM_DIAS = {31,28,31,30,31,30,31,31,30,31,30,31}

// NUM_DIAS[i] = nº días del mes, 0<=i<=11 double[][] tempMed = new double[12][]; // tempMed[i] representa el mes, 0<=i<=11 for (int i=0; i<tempMed.length; i++) tempMed[i] = new double[NUM_DIAS[i]]; // el nº elementos de tempMed[i] = NUM_DIAS[i], 0<=i<=11

Page 48: Introducción a la programación y la informática. Tema 10

Arrays Multidimensionales Ejemplo: Temperatura (III)

• Alternativa de implementación usando numeración desde 1.

• Ahora, tempMed[i][j] representa la temperatura media del día j del

mes i. – tempMed[4][15] es la temperatura media del 15 de Abril.

25/11/2011 IIP - Curso 2011/12 48

final int[] NUM_DIAS = {0,31,28,31,30,31,30,31,31,30,31,30,31}; // NUM_DIAS[0] = 0 y NUM_DIAS[i] = nº días del mes i, 1<=i<=12 double[][] tempMed = new double[13][]; // tempMed[0] = null y tempMed[i] representa el mes i, 1<=i<=12 for (int i=1; i<tempMed.length; i++) tempMed[i] = new double[NUM_DIAS[i]+1]; // el nº elementos de tempMed[i] = NUM_DIAS[i]+1, 1<=i<=12

Page 49: Introducción a la programación y la informática. Tema 10

Arrays de dimensión N • Para dimensiones mayores que dos se siguen las mismas reglas.

Por ejemplo:

• Tres dimensiones:

• Cuatro dimensiones:

De forma equivalente:

25/11/2011 IIP - Curso 2011/12 49

int[][][] tres = {{{1}},{{1,2},{3,4}},{{1},{2}}}; int[][] dos = {{5,4},{6,7}}; tres[1] = dos; tres[1][0][1] = 6;

int[][][][] cuatro = new int[10][2][][]; for(int i=0; i<cuatro.length; i++) for(int j=0; j<cuatro[i].length; j++) cuatro[i][j] = new int[3][3];

int[][][][] cuatro = new int[10][2][3][3];

Page 50: Introducción a la programación y la informática. Tema 10

Recorrido de arrays multidimensionales

• Suma de dos matrices de double de dimensión NxM

• Se asume que m1 y m2 están inicializadas y ambas tienen dimensiones NxM

25/11/2011 IIP - Curso 2011/12 50

public static double[][] sumaM(double[][] m1, double[][] m2) {

double[][] res= new double[m1.length][m1[0].length];

for (int i=0; i<m1.length; i++)

for (int j=0; j<m1[i].length; j++)

res[i][j]= m1[i][j] + m2[i][j];

return res;

}

+ =

Page 51: Introducción a la programación y la informática. Tema 10

Recorrido de arrays multidimensionales

• Producto matriz por vector:

• El nº de columnas de la matriz debe coincidir con el tamaño del vector.

25/11/2011 IIP - Curso 2011/12 51

public static double[] matPorVec(double[][] m, double[] v) {

double[] res = new double[m.length];

for (int i=0; i<m.length; i++)

for (int j=0; j<v.length; j++)

res[i] += m[i][j] * v[j];

return res;

}

m v

* =

res

Page 52: Introducción a la programación y la informática. Tema 10

Búsqueda en array multidimensional • En el ejemplo de las temperaturas, búsqueda de la fecha en la

que se registraron 40º.

25/11/2011 IIP - Curso 2011/12 52

public static void main(String[] args) { final int[] NUM_DIAS = {0,31,28,31,30,31,30,31,31,30,31,30,31}; double[][] tempMed = new double[13][]; for (int i=1; i<tempMed.length; i++) tempMed[i] = new double[NUM_DIAS[i]+1];

..... int i = 1, j = 1; boolean encontrado = false; while (i<tempMed.length && !encontrado) { while (j<tempMed[i].length && !encontrado) { encontrado = (tempMed[i][j]==40); j++; } i++; } if (encontrado) { System.out.print("40º medido el día " + (j-1)); System.out.println(" del mes " + (i-1)); } else System.out.println("Ningún día con 40º"); }

Page 53: Introducción a la programación y la informática. Tema 10

Más problemas de acceso directo

25/11/2011 IIP - Curso 2011/12 53

• El array permite el acceso en tiempo constante a cualquier componente, conocida su posición. – Dado el array a[0..1000], a[0] tiene el mismo coste temporal (teórico)

que a[999].

• Esto permite implementar algunos algoritmos de forma muy eficiente. Ejemplos:

• Búsqueda binaria o dicotómica – Permite la búsqueda eficiente sobre un array ordenado.

• Representación de un conjunto de naturales

• Cálculo de la moda de un conjunto de naturales • El miembro del conjunto que más veces se repite.

Page 54: Introducción a la programación y la informática. Tema 10

Búsqueda binaria: estrategia • Aplicable únicamente a arrays ordenados (ascendentemente en

este caso).

• Estrategia: Buscar el elemento 12

25/11/2011 IIP - Curso 2011/12 54

2 4 5 7 9

0 1 2 3 4

12

5

a zona de búsqueda 15

6

2 4 5 7 9 12 a 15

2 4 5 7 9 12 a 15

Calcular el elemento central y decidir proseguir la búsqueda por una mitad u otra del array

La búsqueda ha finalizado con éxito

4 6

5

Page 55: Introducción a la programación y la informática. Tema 10

Búsqueda binaria: implementación • Implementación de búsqueda binaria: Encontrar x en el array

ordenado ascendentemente: a[inicio…fin].

25/11/2011 IIP - Curso 2011/12 55

public static int busBinaria(int[] a, int inicio, int fin,

int x){

int izq = inicio, der = fin, mitad = 0;

boolean encontrado = false;

while (izq<=der && !encontrado) {

mitad = (izq+der)/2;

if (x==a[mitad]) encontrado = true;

else if (x<a[mitad]) der = mitad-1;

else izq = mitad+1;

}

if (encontrado) return mitad;

else return -1;

}

Page 56: Introducción a la programación y la informática. Tema 10

int izq = 0, der = a.length-1, mitad = 0; boolean enc = false; while(izq<=der && !enc) { mitad = (izq+der)/2; if (x==a[mitad]) enc = true; else if (x<a[mitad]) der = mitad-1; else izq = mitad+1; } if (encontrado) return mitad; else return -1;

25/11/2011 IIP - Curso 2011/12 56

0 3 4 6 7 8 10 17 a 20 x

0 1 2 3 4 5 6 7 izq der

0 3 4 6 7 8 10 17 a

0 1 2 3 4 5 6 7 izq der mitad

0 3 4 6 7 8 10 17 a

0 1 2 3 4 5 6 7 izq der mitad

0 3 4 6 7 8 10 17 a

0 1 2 3 4 5 6 7 izq

der mitad

0 3 4 6 7 8 10 17 a

0 1 2 3 4 5 6 7 izq der

mitad

1ª iter.

2ª iter.

3ª iter.

4ª iter.

n/2

n/22

n/23

n = a.length

n/2límite = 1

límite = log2n

log2n+1 iteraciones

Page 57: Introducción a la programación y la informática. Tema 10

Representación de un conjunto de naturales (I)

• Representación de un conjunto de números naturales en el intervalo [0..n] mediante un array conjunto de boolean donde: – conjunto[i]=true si i pertenece al conjunto (false en caso contrario)

25/11/2011 IIP - Curso 2011/12 57

true true true false true

conjunto

public class Conjunto { private boolean[] conjunto; private int ultimo; public Conjunto(int ult) { conjunto = new boolean[ult+1]; ultimo = ult; } /** 0<=x<=ultimo */ public boolean pertenece(int x) { return conjunto[x]; }

Page 58: Introducción a la programación y la informática. Tema 10

Representación de un conjunto de naturales (II)

• Esta representación permite conocer de forma muy rápida (tiempo independiente del número de elementos) si un natural pertenece o no al conjunto.

25/11/2011 IIP - Curso 2011/12 58

public int cardinal() { int card = 0; for (int i=0; i<conjunto.length; i++) if (conjunto[i]) card++; return card; } /** 0<=x<=ultimo */ public void añade(int x) { conjunto[x] = true; }

public void setAlAzar() { for (int i=0; i<conjunto.length; i++) conjunto[i] = (Math.random()>=0.5); } ... }

Page 59: Introducción a la programación y la informática. Tema 10

Moda de un conjunto de naturales • La moda de un conjunto es el elemento del mismo que más veces

aparece.

• Estrategia en dos fases:

– Fase 1: Recorrido secuencial ascendente y array auxiliar de contadores (frecuencia) donde frecuencia[i]: nº de veces que aparece i en el array.

– Fase 2: La moda se obtiene calculando el máximo del array frecuencia.

• Ejemplo para C={5,7,1,7,8,7,3,0,7,8,5,0} con n = 8 (numero más grande)

25/11/2011 IIP - Curso 2011/12 59

a

5 7 1 7 8

0

7 3

11

0 7 8 5 0

frecuencia

2 1 0 1 0

0

2 0 2

1 2 3 4 5 6 7 8

4

El tamaño de este array se corresponde con el número natural más grande a representar

Page 60: Introducción a la programación y la informática. Tema 10

Moda de un conjunto de naturales • Calcula la moda de un array que contiene elementos enteros en el rango [0..n]

25/11/2011 IIP - Curso 2011/12 60

public static int modaDe0aN(int[] a, int n) {

// se construye un array entre 0 y n

int[] frecuencia = new int[n+1];

// recorrido de a y obtención de frecuencias

for (int i=0; i<a.length; i++) frecuencia[a[i]]++;

// la moda es el máximo del array frecuencia

int moda = 0;

for (int i=1; i<frecuencia.length; i++)

if (frecuencia[i]>frecuencia[moda]) moda = i;

return moda;

}