Tt 10-cas-x1

40 %
60 %
Information about Tt 10-cas-x1
Education

Published on March 20, 2014

Author: andresgarciagarcia921

Source: slideshare.net

Description

Introduccion a la programación y la informática, Universitat Politècnica de València.

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

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

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

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

• 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

• 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

• 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

• 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

• 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

• 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

• 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 0v1 v2 0 1 2 3 1 3 2 0 0 1 2 3 Arrays unidimensionales - Asignación

• 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

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; } }

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); }

• 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

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; } }

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.

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); } }

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

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 }

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 }

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; }

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)

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; }

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; }

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; }

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

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

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

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

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;

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

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])

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; }

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; }

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; }

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; }

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

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

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 12filas 31 columnas 0 30 Esta representación desperdicia memoria

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 12filas 0 3029 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

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

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

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]

• 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();

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

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

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

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];

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; } + =

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

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º"); }

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.

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úsqueda15 6 2 4 5 7 9 12a 15 2 4 5 7 9 12a 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

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; }

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 17a 20x 0 1 2 3 4 5 6 7izq der 0 3 4 6 7 8 10 17a 0 1 2 3 4 5 6 7izq der mitad 0 3 4 6 7 8 10 17a 0 1 2 3 4 5 6 7izq der mitad 0 3 4 6 7 8 10 17a 0 1 2 3 4 5 6 7izq dermitad 0 3 4 6 7 8 10 17a 0 1 2 3 4 5 6 7 izqder 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

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]; }

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); } ... }

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

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; }

Add a comment

Related presentations