Está en la página 1de 52

ESTRUCTURA DE DATOS: LOS ARRAYS O ARREGLOS

Introducción: Esta lección tratará un tema muy importante en cualquier lenguaje de programación: los arreglos. No
es posible enfatizar sobremanera la importancia de los arreglos, pues ellos mismos dan origen a muchas aplicaciones.
En muchas ocasiones, sus programas requerirán almacenar varios valores, tales como 50 calificaciones, 10 títulos de
libros, 1000 nombres de archivos, etc. Cuando sus programas necesitan almacenar varios valores, entonces define un
arreglo, especificando su clase de datos, nombre y número de elementos que el arreglo almacenará.

Definición: Un arreglo es una colección de objetos numerados del mismo tipo, en donde cada variable o celda en el
arreglo tiene un índice, son tratados como una unidad. Las celdas están numeradas del 0 al N-1, donde N es el número
de celdas del arreglo es decir su capacidad.
Los índices de un arreglo en Java deben estar dentro de los límites, 0 – N-1, de lo contrario se generará un error durante
la ejecución.
Un arreglo es una colección finita, homogénea y ordenada de elementos.
- Finita: Todo arreglo tiene un límite; es decir debe determinarse cual será el número máximo de elementos que
podrán formar parte del arreglo.
- Homogénea: Todos los elementos de un arreglo son del mismo tipo (todos enteros, todos reales, etc.)
- Ordenada: se puede determinar cuál es el primer elemento, el segundo, el tercero.... y el enésimo elemento.

Un arreglo es una estructura de datos indexados que se utiliza para almacenar elementos de datos de la misma clase.

Los arreglos son estructuras de datos consistentes en elementos de datos relacionados del mismo tipo.

Tipos: Los datos a procesar por una computadora pueden clasificarse en: Simples y Estructurados.

Numéricos Entero
Real
Simples
Carácter
No numéricos Cadena de Caracteres
Booleano
Vector
Estáticas Matriz
Poliedro
Tipos de
Datos Internas Punteros
Listas
Dinámicas Pilas
Estructura de Colas
Datos Arboles

Secuencial
Archivos Directo
Externas Indexado
Base de Datos

Estructura de datos interna: Reside en la memoria central de la computadora.

Estructura de datos externa: Reside en un soporte externo.

Estructuras estáticas: Son aquellas en las que el tamaño ocupado en memoria se define antes de que el programa se
ejecute y no puede modificarse dicho tamaño durante la ejecución del programa. Estas estructuras están
implementadas en casi todos los lenguajes. array (vectores/tablas-matrices), registros, ficheros o archivos. Tienen un
número fijo de elementos. Se asigna una cantidad fija de memoria, cuando se declara la variable.

Estructuras dinámicas: El número de elementos varía a lo largo de la ejecución del programa. La ocupación en
memoria puede aumentar o disminuir en tiempo de ejecución.
No tienen las limitaciones o restricciones en el tamaño de memoria ocupada que son propias de las estructuras
estáticas: Mediante el uso de un tipo de datos especifico, denominado puntero, es posible construir estructuras de
datos dinámicas que son soportadas por la mayoría de los lenguajes que ofrecen soluciones eficaces y efectivas en la
1
solución de problemas complejos. Las estructuras dinámicas por excelencia son las listas enlazadas, pilas, colas,
arboles binarios, árbol-b, búsqueda binaria y grafos.

Los arreglos simplemente proporcionan un medio organizado para localizar y almacenar datos, así como el apartado
postal en el correo de su oficina postal local proporciona un medio organizado de localizar y clasificar el correo. Por
esto a un arreglo se le conoce como una estructura de datos que se usa para almacenar cualquier clase de datos,
incluyendo enteros, flotantes, caracteres, arreglos, apuntadores, y registros Además, los arreglos son tan versátiles que
se pueden usar para implementar otras estructuras de datos, como pilas, colas, listas ligadas y árboles binarios. Por
medio del uso de arreglos es posible implementar la mayor parte de otras estructuras.

Estructura de un Arreglo
Un arreglo es una estructura de datos. En otras palabras, un arreglo consta de elementos de datos organizados o
estructurados en una forma particular. Esta estructura de datos proporciona un medio conveniente para almacenar
grandes cantidades de datos en la memoria primaria o del usuario. Existen arreglos unidimensionales o vectores y
multidimensionales.

Es un conjunto de datos del mismo tipo almacenados en la memoria del computador en posiciones adyacentes. Sus
componentes individuales se llaman elementos y se distinguen entre ellos por el nombre del array seguido de uno o
varios índices o subíndices. Estos elementos se pueden procesar, bien individualmente, determinando su posición
dentro del array, bien como array completo. El número de elementos del array se especifica cuando se crea este, en la
fase declarativa del programa, definiendo el número de dimensiones o número de índices del mismo y los límites
máximo y mínimo que cada uno de ellos puede tomar, que llamaremos rango. Según sea este número, distinguiremos
los siguientes tipos de array:

Clasificación: Los arrays se clasifican en


✓ Arrays unidimensionales (vectores)
✓ Arrays bidimensionales (Matrices)
✓ Arrays multidimensional

1) ARREGLOS (ARRAYS) UNIDIMENSIONALES: LOS VECTORES


Un array o arreglo (matriz o vector) es un conjunto finito y ordenado de elementos homogéneos y bajo un nombre
común para todos ellos. La propiedad “ordenado” significa que el elemento primero, segundo, tercero,…, enésimo
de un array puede ser identificado. Los elementos de un array son homogéneos, es decir, del mismo tipo de datos.
Un array puede estar compuesto de todos sus elementos de tipo cadena, otro puede tener todos sus elementos de tipo
entero, etc. Los arrays se conocen también como matrices-en matemáticas- y tablas en cálculos financieros.

El tipo más simple de array es el array unidimensional o vector (matriz de una dimensión). Un vector denominado
Notas que consta de n elementos se puede representar en la figura siguiente:

Ejemplo, se tienen las notas de 50 estudiantes de un examen de Fundamentos de Programación.


Partes de un arreglo: Los componentes, los índices y el nombre del arreglo. Los componentes hacen referencia a los
elementos que forman el arreglo; es decir a los valores que se almacenan en cada una de las casillas del mismo. Los
índices permiten hacer referencia a los componentes del arreglo en forma individual; es decir, distinguir entre los
elementos del mismo.
Notas

Notas[0] 11

Notas[1] 13

Notas[2] 10

............. .......
.Notas[49] 12

Nombre del arreglo: Notas


Índice del vector: Notas[ i ] . El subíndice o índice de un elemento (0, 1, 2,…, i, n-1) designa su posición en la
ordenación del vector. Otras posibles notaciones del vector son:

2
A(0), A(1), A(2), …, A(i), …A(n-1) En VB 6.0 y VB.Net

A[0], A[1], A[2], …, A[i], …A[n-1] En C++, Java

Obsérvese que solo el vector global tiene nombre “Notas”. Los elementos del vector se referencian por su subíndice
o índice, es decir, su posición relativa en el valor

El valor de Notas[49] es: 12


Notas[25] : Posición numérica del elemento dentro del arreglo.

Para dividir el valor del séptimo elemento del arreglo Notas entre 2 y asignar el resultado a la variable x, escribiríamos:
x = Notas[6]/2;

Nota: Es importante notar la diferencia entre el séptimo elemento del arreglo y el “Elemento siete del arreglo”. Dado
que los subíndices de los arreglos empiezan en 0, “El séptimo elemento del arreglo” tiene un subíndice de 6, en tanto
que “El elemento 7 del arreglo“ tiene un subíndice de 7 y de hecho es el octavo elemento del arreglo. Esta confusión
es fuente de errores de “desplazamiento en uno”

El valor mínimo permitido de un vector se denomina límite inferior del vector (Li) y el valor máximo permitido se
denomina límite superior (Ls)
En el ejemplo del vector Notas el límite inferior es 0 y el límite superior 49.

El número de elementos de un vector se denomina rango del vector. El rango del vector notas es 50.

Consideremos un vector X de 8 elementos

X[0] X[1] X[2] X[3] X[4] X[5] X[6] X[7]


14.0 12.0 8.0 7.0 6.41 5.23 6.15 7.25
Elemento 1º Elemento 2º Elemento 8º

Algunas instrucciones que manipulan este vector se representa en la tabla siguiente


Acciones Resultados
Escribir (X[0]) Visualiza el valor de X[0] o 14.0
X[3] = 45 Almacena el valor 45 en X[3]
Suma = X[0] + X[2] Almacena en la variable Suma el valor de X[0] y X[2] o bien 22.0 en la variable suma.
Suma = Suma + X[3] Añade a la variable Suma el valor de X[3], es decir, Suma = 67.0
X[4] = X[4] + 3.5 Suma 3.5 a X[4]; el nuevo valor de X[4] será 9.91
X[5] = X[0] + X[1] Almacena la suma de X[0] y X[1] en X[5]; el nuevo valor de X[5] será 26.5
Operaciones básica s con vectores.

Declaracion de un Vector: La declaración de un array unidimensional se hace con esta sintaxis.

Tipo_dato nombre_arreglo[tamaño_arreglo];

Donde tipo_dato corresponde al tipo de los elementos que contendrá el arreglo (enteros, reales, caracteres, etc...),
nombre_arreglo corresponde al nombre con el cual se denominará el arreglo.
Ejemplo:

real cuentas[];

Declara un array de tipo double. Esta declaración indica para qué servirá el array, pero no reserva espacio en la
RAM al no saberse todavía el tamaño del mismo.
Tras la declaración del array, se tiene que iniciar. Eso lo realiza el operador new, que es el que realmente crea el
array indicando un tamaño. Cuando se usa new es cuando se reserva el espacio necesario en memoria. Un array no
inicializado es un array null.

En Java, un arreglo se declara de la misma forma que cualquier otra variable, generalmente al principio de una clase
o de un método. Un arreglo es un objeto y, por lo tanto, debe crearse mediante el operador new, para crear una
instancia de la clase array. El programador da un nombre al arreglo, de la siguiente forma:

int []Edades; //Declara la variable arreglo


String []Grupo;

3
La variable llamada edades ahora está preparada para hacer referencia a un arreglo de enteros. Al igual que con
cualquier otra variable, es común (y conveniente) elegir un nombre para el arreglo que describa claramente su función.
El nombre viene siendo el nombre del arreglo completo, la colección completa de datos. Las reglas para elegir el
nombre del arreglo son las mismas que para elegir cualquier otro nombre en Java.

Al crear un arreglo con new, tiene que indicar su longitud (cuantos elementos va a contener) y el tipo de objetos que
van a estar contenidos en el arreglo:

Edades = new int[6]; //Crea el arreglo


Grupo = new String[4];

El arreglo llamado Edades es lo suficientemente grande como para contener seis números, en donde sus índices van
desde 0 hasta 5.

El arreglo llamado Grupo es lo suficientemente grande como para contener cuatro cadenas. Los índices van de 0 a 3.
Puede declarar una variable de arreglo y crearla, todo dentro de la misma instrucción, como se muestra a
continuación.
int [ ]Edades = new int[6];
String [ ]Grupo = new String[4];

Inicialización de un arreglo
Inicializar significa dar a una variable un valor inicial o de comienzo. Si escribe esto;
int [ ] Tabla = new int[10];

Al crear un arreglo, se establece un arreglo en memoria; cada uno de sus elementos recibe un valor predeterminado:
cero para los elementos numéricos de tipos primitivos, false para los elementos boolean y null para las referencias
(cualquier tipo de datos no primitivo).

Una manera común de inicializar un arreglo es hacerlo cuando se declare el mismo. La siguiente inicialización:

int [ ] Edades = {23, 54, 96, 13, 7, 32};

Es equivalente a:
int [ ] Edades = new int[6];
Edades[0] = 23;
Edades[1] = 54;
Edades[2] = 96;
Edades[3] = 13;
Edades[4] = 7;
Edades[5] = 32;

Otro ejemplo, utilizando un arreglo de cadenas, sería:


String [ ] Grupo = {“John”, “Paul”, “George”, “Ringo”};

Otra manera de inicializar un arreglo es mediante un ciclo:


for(int i = 0; i < 10; i++)
Tabla[i] = 0;

Operaciones con Vectores


a. Lectura de un vector: Consiste en asignar el valor de los elementos a un vector. La escritura o lectura de un
vector se debe ser elemento a elemento utilizando estructuras repetitivas, concretamente bucles for.
La instrucción simple de lectura se representa como
Leer (V[2])

Código en Java de un ingreso de datos a un Vector


private void jBJOptionPaneActionPerformed(java.awt.event.ActionEvent evt) {
int n, e;
String n1, dato;
n1 = JOptionPane.showInputDialog("Ingrese Cantidad de n:");
n = Integer.parseInt(n1);
for(int i = 0; i < n; i++)

4
{
dato = JOptionPane.showInputDialog("Ingrese elemento:");
e = Integer.parseInt(dato);
obj.setIngreso(e);
}
}

b. Escritura de un vector: Consiste en recorrer todo el arreglo para reportar el valor de sus elementos. La
lectura/Escritura de datos de arrays u operaciones de entrada/salida normalmente se realizan con estructuras
repetitivas. Es recomendable utilizar bucles for.

public void Reporte()


{
for(int i=0; i<obj.c; i++)
this.jTASalida.append(""+obj.getReporte(i)+"\n");
}
c. Ordenación: Es la operación de organizar un conjunto de datos en algún orden dado, tal como creciente o
decreciente en datos numéricos, de carácter o cadena de caracteres.
Los métodos más conocidos de ordenamiento son: Burbuja, Shell y Quicksort.

Método de Ordenamiento de la burbuja:


El Ordenamiento de burbuja (Bubble Sort en inglés) es un sencillo algoritmo de ordenamiento. Funciona revisando
cada elemento de la lista que va a ser ordenada con el siguiente, intercambiándolos de posición si están en el orden
equivocado. Es necesario revisar varias veces toda la lista hasta que no se necesiten más intercambios, lo cual significa
que la lista está ordenada. Este algoritmo obtiene su nombre de la forma con la que suben por la lista los elementos
durante los intercambios, como si fueran pequeñas "burbujas". También es conocido como el método del intercambio
directo. Dado que solo usa comparaciones para operar elementos, se lo considera un algoritmo de comparación, siendo
el más sencillo de implementar.
Se basa en el principio de comparar pares de elementos adyacentes e intercambiarlos entre sí hasta que estén todos
ordenados.

Notas

Notas[0] 12
Notas[1] 8
Notas[2] 5
Notas[3].. 10
..Notas[5]
4

i = Número de la pasada
j = Indica el orden del elemento de la lista o el número de comparaciones.
Pasada 1

Ordenamiento de los datos al final de la primera pasada (Se aprecia que el primer elemento, que es 4, ha burbujeado
a la superficie)

Pasada 2

5
Ordenamiento de los datos al final de la segunda pasada (Se observa que el segundo elemento menor que para el
ejemplo es 5, se ha colocado en su lugar)

Pasada 3

Ordenamiento de los datos al final de la tercera pasada (Se observa que el tercer elemento menor que para el
ejemplo es 8, se ha colocado en su lugar)

Pasada 4

Ordenamiento de datos al final de la cuarta pasada: Se observa a los datos ordenados totalmente

De acuerdo al ejemplo al ejemplo observamos que necesitamos 4 pasadas para ordenar la lista de 5 elementos, por lo
que una lista de n elementos necesitará n-1 pasadas; por lo tanto i varía desde 1 hasta n-1.
También observamos que:
Para la pasada 1 ( i = 1 ), se realizan 4 (5-1 ) comparaciones ( j = 1, 2, 3, 4 )
Para la pasada 2 ( i = 2 ), se realizan 3 (5-2 ) comparaciones ( j = 1, 2, 3 )
Para la pasada 3 ( i = 3 ), se realizan 2 (5-3 ) comparaciones ( j = 1, 2 )
Para la pasada 4 ( i = 4 ), se realizan 1 (5-4 ) comparaciones ( j = 1 )

public void ordenaBurbuja()


{
double aux;
for(int i=0; i<c-1; i++)
for(int j = i+1; j <c; j++)
if(V[i] > V[j])
{
aux = V[i];
V[i] = V[j];
V[j] = aux;

6
}
}

Método de Ordenamiento Shell:


El ordenamiento Shell (Shell sort en inglés) es un algoritmo de ordenamiento. El método se denomina Shell en
honor de su inventor Donald Shell. Su implementación original, requiere O(n2) comparaciones e intercambios en el
peor caso. Un cambio menor presentado en el libro de V. Pratt produce una implementación con un rendimiento de
O(nlog2 n) en el peor caso. Esto es mejor que las O(n2) comparaciones requeridas por algoritmos simples pero peor
que el óptimo O(n log n). Aunque es fácil desarrollar un sentido intuitivo de cómo funciona este algoritmo, es muy
difícil analizar su tiempo de ejecución.
El Shell sort es una generalización del ordenamiento por inserción, teniendo en cuenta dos observaciones:
1. El ordenamiento por inserción es eficiente si la entrada está "casi ordenada".
2. El ordenamiento por inserción es ineficiente, en general, porque mueve los valores sólo una posición cada
vez.
El algoritmo Shell sort mejora el ordenamiento por inserción comparando elementos separados por un espacio de
varias posiciones. Esto permite que un elemento haga "pasos más grandes" hacia su posición esperada. Los pasos
múltiples sobre los datos se hacen con tamaños de espacio cada vez más pequeños. El último paso del Shell sort es un
simple ordenamiento por inserción, pero para entonces, ya está garantizado que los datos del vector están casi
ordenados.

Es una mejora del método de la burbuja que consiste en comparar pares de elementos e intercambiarlos entre sí en
saltos de mayor longitud.
Se repite el mismo proceso con una distancia de comparación que inicialmente es la mitad de la longitud del
vector y que se va reduciendo a la mitad en cada repetición hasta que dicha distancia vale 1.
Cada pasada termina al detectarse mediante un switch la ordenación a la distancia correspondiente.

El método de shell es una versión mejorada del método de inserción directa recibe ese nombre en honor a su autor
Donald L. Shell quien lo propuso en 1959.
Este método también se conoce con el nombre de inserción con incrementos decrecientes.
En el método de ordenación Shell propone que las comparaciones entre elementos se efectúen con saltos de mayor
tamaño pero con incrementos se efectúen con saltos de mayor tamaño pero con incrementos decrecientes, así los
elementos quedarán ordenados en el arreglo.

7
Ejercicio: Por ejemplo, considere una lista de números como [ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ].
Si comenzamos con un tamaño de paso de 5, podríamos visualizar esto dividiendo la lista de números en una tabla
con 5 columnas. Esto quedaría así:
13 14 94 33 82
25 59 94 65 23
45 27 73 25 39
10

Entonces ordenamos cada columna, lo que nos da


10 14 73 25 23
13 27 94 33 39
25 59 94 65 82
45
Cuando lo leemos de nuevo como una única lista de números, obtenemos [ 10 14 73 25 23 13 27 94 33 39 25 59 94
65 82 45 ]. Aquí, el 10 que estaba en el extremo final, se ha movido hasta el extremo inicial. Esta lista es entonces
de nuevo ordenada usando un ordenamiento con un espacio de 3 posiciones, y después un ordenamiento con un
espacio de 1 posición (ordenamiento por inserción simple).

Ejemplo:
Se desean ordenarse las siguientes clave del arreglo
A: 15, 67, 08, 16, 44, 27, 12, 35, 56, 21, 13, 28, 60, 36, 07, 10

Primera Pasada
Los elementos se dividen en 8 grupos:
A: 15, 67, 08, 16, 44, 27, 12, 35 | 56, 21, 13, 28, 60, 36, 07, 10

La ordenación produce:
A: 15, 21, 08, 16, 44, 27, 07, 10, 56, 67, 13, 28, 60, 36, 12, 35

Segunda Pasada
Se dividen los elementos en 4 grupos:

8
A: 15, 21, 08, 16 | 44, 27, 07, 10 | 56, 67, 13, 28 | 60, 36, 12, 35

La ordenación produce:
A: 15, 21, 07, 10, 44, 27, 08, 16, 56, 36, 12, 28, 60, 67, 13, 35

Tercera Pasada
Se divide los elementos 2 grupos
A: 15, 21 | 07, 10 | 44, 27 | 08, 16 | 56, 36 | 12, 28 | 60, 67 | 13, 35

La ordenación produce:
A = 07, 10, 08, 16, 12, 21, 13, 27, 15, 28, 44, 35, 56, 36, 60, 67

Cuarta Pasada
Divida los elementos en un solo grupo.
La ordenación produce:
A: 07, 08, 10, 12, 13, 15, 16, 21, 27, 28, 35, 36, 44, 56, 60, 67

Ejemplo ordenar ascendentemente la lista o vector (Código en Java):


public void ordenaShell()
{
double aux;
int ban, salto;
salto = c/2;
do{
do{
ban = 0;
for( int i = 0; i < c - salto; i++ )
if( V[i] > V[i + salto])
{
aux = V[i];
V[i] = V[i + salto];
V[i + salto] = aux;
ban = 1;
}
}while( ban != 0 );
salto = salto/2;
}while( salto != 0 );
}

Ordenamiento Método QuickSort


El ordenamiento rápido (quicksort en inglés) es un algoritmo basado en la técnica de divide y vencerás, que
permite, en promedio, ordenar n elementos en un tiempo proporcional a n log n.

Descripción del algoritmo


El algoritmo fundamental es el siguiente:
✓ Elegir un elemento de la lista de elementos a ordenar, al que llamaremos pivote.
✓ Resituar los demás elementos de la lista a cada lado del pivote, de manera que a un lado queden todos los
menores que él, y al otro los mayores. Los elementos iguales al pivote pueden ser colocados tanto a su derecha
como a su izquierda, dependiendo de la implementación deseada. En este momento, el pivote ocupa
exactamente el lugar que le corresponderá en la lista ordenada.
✓ La lista queda separada en dos sublistas, una formada por los elementos a la izquierda del pivote, y otra por
los elementos a su derecha.
✓ Repetir este proceso de forma recursiva para cada sublista mientras éstas contengan más de un elemento.
Una vez terminado este proceso todos los elementos estarán ordenados.

Como se puede suponer, la eficiencia del algoritmo depende de la posición en la que termine el pivote elegido.
✓ En el mejor caso, el pivote termina en el centro de la lista, dividiéndola en dos sublistas de igual tamaño. En
este caso, el orden de complejidad del algoritmo es O(n·log n).
✓ En el peor caso, el pivote termina en un extremo de la lista. El orden de complejidad del algoritmo es entonces
de O(n²). El peor caso dependerá de la implementación del algoritmo, aunque habitualmente ocurre en listas
que se encuentran ordenadas, o casi ordenadas. Pero principalmente depende del pivote, si por ejemplo el

9
algoritmo implementado toma como pivote siempre el primer elemento del array, y el array que le pasamos
está ordenado, siempre va a generar a su izquierda un array vacío, lo que es ineficiente.

Técnicas de elección del pivote


El algoritmo básico Quicksort permite tomar cualquier elemento de la lista como pivote, dependiendo de la partición
n que se elija, el algoritmo será más o menos eficiente.
✓ Tomar un elemento cualquiera como pivote tiene la ventaja de no requerir ningún cálculo adicional, lo cual
lo hace bastante rápido. Sin embargo, esta elección «a ciegas» siempre provoca que el algoritmo tenga un
orden de O(n²) para ciertas permutaciones de los elementos en la lista.
✓ Otra opción puede ser recorrer la lista para saber de antemano qué elemento ocupará la posición central de
la lista, para elegirlo como pivote. Esto puede hacerse en O(n) y asegura que hasta en el peor de los casos, el
algoritmo sea O(n·log n). No obstante, el cálculo adicional rebaja bastante la eficiencia del algoritmo en el
caso promedio.
✓ La opción a medio camino es tomar tres elementos de la lista - por ejemplo, el primero, el segundo, y el
último - y compararlos, eligiendo el valor del medio como pivote.
✓ En el caso promedio, el orden es O(n·log n).
No es extraño, pues, que la mayoría de optimizaciones que se aplican al algoritmo se centren en la elección del pivote.

Ejemplo
En el siguiente ejemplo se marcan el pivote y los índices i y j con las letras p, i y j respectivamente.
Comenzamos con la lista completa. El elemento pivote será el 4:
5 - 3 - 7 - 6 - 2 - 1 - 4
p

Comparamos con el 5 por la izquierda y el 1 por la derecha.


5 - 3 - 7 - 6- 2 - 1 - 4
i j p

5 es mayor que 4 y 1 es menor. Intercambiamos:


1 - 3 - 7 - 6 - 2 - 5 - 4
i j p

Avanzamos por la izquierda y la derecha:


1 - 3 - 7 - 6 - 2 - 5 - 4
i j p

3 es menor que 4: avanzamos por la izquierda. 2 es menor que 4: nos mantenemos ahí.
1 - 3 - 7 - 6 - 2 - 5 - 4
i j p

7 es mayor que 4 y 2 es menor: intercambiamos.


1 - 3 - 2 - 6 - 7 - 5 - 4
i j p

Avanzamos por ambos lados:


1 - 3 - 2 - 6 - 7 - 5 - 4
ij p

En este momento termina el ciclo principal, porque los índices se cruzaron. Ahora intercambiamos lista[i] con lista
[sup] (pasos 16-18):

1 - 3 - 2 - 4 - 7 - 5 - 6
p

Aplicamos recursivamente a la sublista de la izquierda (índices 0 - 2). Tenemos lo siguiente:


1 - 3 - 2

1 es menor que 2: avanzamos por la izquierda. 3 es mayor: avanzamos por la derecha. Como se intercambiaron los
índices termina el ciclo. Se intercambia lista[i] con lista[sup]:
1 - 2 - 3

10
El mismo procedimiento se aplicará a la otra sublista. Al finalizar y unir todas las sublistas queda la lista inicial
ordenada en forma ascendente.

1 - 2 - 3 - 4 - 5 - 6 - 7

http://es.wikipedia.org/wiki/Quicksort

El método de ordenamiento Quick Sort es actualmente el más eficiente y veloz de los métodos de ordenación interna.
Es también conocido con el nombre del método rápido y de ordenamiento por partición, en el mundo de habla hispana.

Este método es una mejora sustancial del método de intercambio directo y recibe el nombre de Quick Sort por la
velocidad con que ordena los elementos del arreglo.

La idea central de este algoritmo consiste en el siguiente:


Se toma un elemento x de una posición cualquiera del arreglo.

11
Se trata de ubicar a x en la posición correcta del arreglo, de tal forma que todos los elementos que se encuentran a su
izquierda sean menores o iguales a x y todos los elementos que se encuentren a su derecha sean mayores o iguales a
x.

Se repiten los pasos anteriores pero ahora para los conjuntos de datos que se encuentran a la izquierda y a la derecha
de la posición correcta de x en el arreglo.

Ejemplo:
A: 15, 67, 08, 16, 44, 27, 12, 35
Se selecciona A[i] x=15
Para este ejemplo se ingresa los datos desde el índice 1 hasta 8.
Primera pasada (DER-IZQ)
A[8] >= x 35 >= 15 No hay intercambio
A[7] >= x 12 >= 15 Si hay intercambio

A: 12,67,08,16,44,27,15,35

(IZQ-DER)
A[2] < = X 67 < = 15 Si hay intercambio

A:12,15,08,16,44,27,67,35

2da. Pasada (DER-IZQ)


A[6] >= x 27 >= 15 No hay intercambio
A[5] >= x 44 >= 15 No hay intercambio
A[4] >= x 16 >= 15 No hay intercambio
A[3] >= x 08 >= 15 Si hay intercambio

A: 12,08,15,16,44,27,67,35

Como el recorrido de izquierda a derecha debería iniciarse en la misma posición donde se encuentra el elemento x, o
se termina ya que el elemento x, se encuentra en la posición correcta.

A: 12, 08, 15, 16, 44, 27, 67, 35


1er 2do Conjunto
Conjunto
16, 44, 27, 67, 35
X=16

(DER-IZQ)
A[8]>=x No hay intercambio
A[7]>=x No hay intercambio
A[6]>=x No hay intercambio
A[5]>=x No hay intercambio

A: 12, 08, 15, 16, 44, 27, 67, 35


X=44

(DER-IZQ)
A[8]>= x Si hay intercambio

A: 12, 08, 15, 16, 35, 27, 67, 44

(IZQ-DER)
A[6] < = x No hay intercambio
A[7] < = x Si hay intercambio
12, 08, 15, 16, 35, 27, 44, 67
12, 08, 15, 16, 35, 27, 44, 67
35, 27, 44, 67
X=35

(DER-IZQ)
A[8] >= x No hay intercambio
12
A[7] >= x No hay intercambio
A[6] >= x Si hay intercambio
12, 08, 15, 16, 27, 35, 44, 67
12,08
X=12

(DER-IZQ)
A[2]>=x Si hay intercambio

El vector ordenado:
08,12,15,16,27,35,44,67

Código en Java
public void ordenaQuickSort(int l, int r)
{
int i, j;
double x, t;
i = l; j = r;
x = V[(i+j)/2];
do{
while( V[i] < x && i < r ) i++;
while( V[j] > x && j > l ) j--;
if( i <= j )
{
t = V[i];
V[i] = V[j];
V[j] = t;
i++;
j--;
}
}while( i <= j );
if( l < j ) ordenaQuickSort(l, j );
if( i < r ) ordenaQuickSort(i, r );
}

d. Algoritmo de búsqueda
Un algoritmo de búsqueda es aquel que está diseñado para localizar un elemento con ciertas propiedades dentro de
una estructura de datos; por ejemplo, ubicar el registro correspondiente a cierta persona en una base de datos, o la
mejor movida en una partida de ajedrez.
La variante más simple del problema es la búsqueda de un número en un vector.
La búsqueda se refiere a la operación de encontrar la posición de un elemento entre un conjunto de elementos dados:
Lista, matriz, archivo, vector, etc. Los métodos más usuales de búsqueda son: Búsqueda secuencial o lineal y búsqueda
binaria.

Búsqueda Secuencial:
Se utiliza cuando el vector no está ordenado o no puede ser ordenado previamente. Consiste en buscar el elemento
comparándolo secuencialmente (de ahí su nombre) con cada elemento del array hasta encontrarlo, o hasta que se llegue
al final. La existencia se puede asegurar cuando el elemento es localizado, pero no podemos asegurar la no existencia
hasta no haber analizado todos los elementos del array. A continuación se muestra el pseudocódigo del algoritmo:
Compara cada elemento del vector con el valor deseado, hasta que éste se encuentra o se termina de leer el vector
completo. El vector no necesita estar ordenado.
Consiste en recorrer y examinar cada uno de los elementos del array hasta encontrar el o los elementos buscados, o
hasta que se han mirado todos los elementos del array.

Código en Java de la búsqueda secuencial

public int buscaSecuencial(double w)


{
int pos = -1;
for(int i=0; i<c; i++)
if(V[i]==w)
{

13
pos = i;
break;
}
return pos;
}

Búsqueda binaria (dicotómica)


Se utiliza cuando el vector en el que queremos determinar la existencia de un elemento está previamente ordenado.
Este algoritmo reduce el tiempo de búsqueda considerablemente, ya que disminuye exponencialmente el número de
iteraciones necesarias.
Está altamente recomendado para buscar en arrays de gran tamaño. Por ejemplo, en uno conteniendo 50.000.000
elementos, realiza como máximo 26 comparaciones (en el peor de los casos).
Para implementar este algoritmo se compara el elemento a buscar con un elemento cualquiera del array (normalmente
el elemento central): si el valor de éste es mayor que el del elemento buscado se repite el procedimiento en la parte
del array que va desde el inicio de éste hasta el elemento tomado, en caso contrario se toma la parte del array que va
desde el elemento tomado hasta el final. De esta manera obtenemos intervalos cada vez más pequeños, hasta que se
obtenga un intervalo indivisible. Si el elemento no se encuentra dentro de este último entonces se deduce que el
elemento buscado no se encuentra en todo el array.
A continuación se presenta el pseudocódigo del algoritmo, tomando como elemento inicial el elemento central del
array.

Este método es válido exclusivamente para vectores ordenados y consiste en comparar en primer lugar con la
componente central del vector, y si no es igual al valor buscado se reduce el intervalo de búsqueda a la mitad derecha
o izquierda, según donde pueda encontrarse el valor a buscar. El programa termina si se encuentra el valor buscado
o si el tamaño del intervalo de búsqueda queda anulado.

Para utilizar este algoritmo, el array debe estar ordenado. La búsqueda binaria consiste en dividir el array por su
elemento medio en dos subarrays más pequeños, y comparar el elemento con el del centro. Si coinciden, la búsqueda
se termina. Si el elemento es menor, debe estar (si está) en el primer subarray, y si es mayor está en el segundo. Por
ejemplo, para buscar el elemento 3 en el array {1, 2, 3, 4, 5, 6, 7, 8, 9} se realizarían los siguientes pasos:

Se toma el elemento central y se divide el array en dos:


{1,2,3,4}-5-{6,7,8,9}
Como el elemento buscado (3) es menor que el central (5), debe estar en el primer subarray: {1,2,3,4}
Se vuelve a dividir el array en dos:
{1}-2-{3,4}
Como el elemento buscado es mayor que el central, debe estar en el segundo subarray: {3,4}
Se vuelve a dividir en dos:
{}-3-{4}
Como el elemento buscado coincide con el central, lo hemos encontrado.
Si al final de la búsqueda todavía no lo hemos encontrado, y el subarray a dividir está vacío {}, el elemento no se
encuentra en el array. La implementación sería:
Código en Java de la búsqueda binaria

public int buscaBinaria(double x)


{
int izq = 0, der = c-1, cen, bin;
cen = ( izq+der )/2;
while( V[cen] != x && izq <= der )
{
if( x > V[cen] ) izq = cen +1;
else der = cen - 1;
cen = ( izq + der )/2;
}
if( V[cen] == x ) bin = cen;
else bin = -1;
return bin;
}

e. Inserción: Consiste en insertar elementos en un vector en una posición indicada. Para que la inserción tenga
sentido, la posición debe estar comprendida en el rango respectivo, es decir entre los limites inferior (0) y el límite
superior(n-1). En el ejemplo se desea insertar un valor X, en la posición 2, del arreglo
14
0 6
1 9 pos = 2
v[6] = v[5]
2 20 v[5] = v[4]
v[4] = v[3]
3 40 v[3] = v[2]
v[pos] = x
4 n=n+1
60
5
70
6

Código en Java de una inserción


public void Inserta(double x, int pos)
{
for(int i = c+1; i >pos; i-- )
V[i] = V[i-1];
V[pos] = x;
c = c + 1;
}

f. Eliminación: La eliminación de un elemento del interior del vector provoca el movimiento hacia arriba de los
elementos inferiores a él para reorganizar el vector.

0 12
1 8 pos = 2
v[2] = v[3]
2 11 v[3] = v[4]
v[4] = v[5]
3 15 n=n-1

4 20

5 30

Código en Java de una eliminación


public void Elimina(int pos)
{
for(int i = pos; i < c-1; i++ )
V[i] = V[i+1];
c = c -1;
}

Paso de arreglos como parámetros


Como hemos visto anteriormente, los métodos soy muy importante en la programación. Un aspecto importante acerca
del uso de los métodos es pasar información a un método en forma de parámetros y devolver un valor. Ahora
explicaremos como pasar y devolver arreglos.
Suponga que deseamos escribir un método cuyo trabajo sea calcular la suma de los componentes de un arreglo de
enteros. Como somos programadores perceptivos, deseamos que el método sea de propósito general, de manera que
15
se acople a arreglos de cualquier longitud. Y eso está bien, ya que el método puede simplemente obtener la longitud
del arreglo. Por lo tanto, el único parámetro que se tiene que pasar al método es el arreglo, y el resultado que se
devolverá al usuario del método es un número, que es la suma de los valores.
Una invocación de ejemplo del método se verá así:

int [ ] Tabla = new int[24], total;


total = suma(tabla)

El método en si viene siendo:


int suma (int [ ] arreglo){
int total = 0;
For(int i=0; i < arreglo.length; i++)
total = total + arreglo[i];
Return total;
}

Observe que, en el encabezado del método, el parámetro se declara como un arreglo, con corchetes. Pero no hay un
parámetro que describa la longitud de la misma. Debido a que puede aceptar un arreglo de cualquier longitud, este
método es de propósito general y de mucha utilidad. Es preferible esto a tener un método de propósito especial que
solo funcione cuando el arreglo contenga, por decir, ocho componentes.
El nombre utilizado para el índice en este método es simplemente i. Este es un ejemplo en el que el nombre elegido
es enigmático. Como el método es de propósito general, no sabemos el propósito del arreglo ni el significado del
índice. Por lo tanto, está bien utilizar un nombre que simplemente indique cualquier índice.

APLICACIÓN CON OPERACIONES BASICAS CON VECTORES: LECTURA, ESCRITURA,


ORDENAMIENTO, BUSQUEDA, INSERCION, ELIMINACION, ETC
1. Crear un nuevo proyecto, con el nombre de JAVectores
2. Crear una nueva clase, con el nombre de CVector, con sus atributos y métodos correspondientes

public class CVector {


protected double V[] =new double[100] ;
protected int c;
public CVector()
{
c = 0;
}

public void setDatos(double x)


{
V[c]=x;
c++;
}

public int getCantidad()


{
return c;
}

public double getDatos(int h)


{
return V[h];
}

public int Busca(double w, int n)


{
int pos = - 1;
for(int i = 0; i < n; i++)
{
if(V[i]==w)
{
pos = i;
break;
}
}
return pos;
}

16
public void ordenaBurbuja()
{
double aux;
for(int i=0; i<c-1; i++)
for(int j = i+1; j <c; j++)
if(V[i] > V[j])
{
aux = V[i];
V[i] = V[j];
V[j] = aux;
}
}

public void ordenaShell()


{
double aux;
int ban, salto;
salto = c/2;
do{
do{
ban = 0;
for( int i = 0; i < c - salto; i++ )
if( V[i] > V[i + salto])
{
aux = V[i];
V[i] = V[i + salto];
V[i + salto] = aux;
ban = 1;
}
}while( ban != 0 );
salto = salto/2;
}while( salto != 0 );
}

public void ordenaQuickSort(int l, int r)


{
int i, j;
double x, t;
i = l; j = r;
x = V[(i+j)/2];
do{
while( V[i] < x && i < r ) i++;
while( V[j] > x && j > l ) j--;
if( i <= j )
{
t = V[i];
V[i] = V[j];
V[j] = t;
i++;
j--;
}
}while( i <= j );
if( l < j ) ordenaQuickSort(l, j );
if( i < r ) ordenaQuickSort(i, r );
}

public int buscaSecuencial(double w)


{
int pos = -1;
for(int i=0; i<c; i++)
if(V[i]==w)
{
pos = i;
break;
}
return pos;
}

public int buscaBinaria(double x)

17
{
int izq = 0, der = c-1, cen, bin;
cen = ( izq+der )/2;
while( V[cen] != x && izq <= der )
{
if( x > V[cen] ) izq = cen +1;
else der = cen - 1;
cen = ( izq + der )/2;
}
if( V[cen] == x ) bin = cen;
else bin = -1;
return bin;
}

public void Inserta(double x, int pos)


{
for(int i = c+1; i >pos; i-- )
V[i] = V[i-1];
V[pos] = x;
c = c + 1;
}

public void Elimina(int pos)


{
for(int i = pos; i < c-1; i++ )
V[i] = V[i+1];
c = c -1;
}
}

3. Agregar un jFrame, con el nombre JFVector, agregue un JTabbedPane (Panel con pestañas) y un Jpanel (Panel)
y crear la interfaz visual siguiente

18
Controles (Objetos) Name Text
JFrame jFVector Title: Operaciones con vectores
JTabbedPane jTabbedPane1
JPanel jPanel1 Titulo de pestaña: Ingreso de datos
ToolTipText: Ingreso de Datos
JLabel jJLabel1 Dato a ingresar:
JTextField jTFDatos
JTextArea jTASalida
JButton jBGuardar Guardar
JButton jBReportar Reportar
JButton jBSalir Salir

4. Al inicio, digitar las siguientes líneas


import javax.swing.JOptionPane;
import javax.swing.JTextArea;

5. Donde corresponda crear el siguiente método

public void Reporte(JTextArea Salida)


{
for(int i = 0; i < A.getCantidad(); i++)
{
Salida.append(""+A.getDatos(i)+"\n");
}
}

6. Codificar los siguientes jButton

private void jBGuardarActionPerformed(java.awt.event.ActionEvent evt) {


double e;
e = Double.parseDouble(this.jTFDatos.getText());
A.setDatos(e);
this.jTFDatos.setText("");
this.jTFDatos.requestFocus();
}

void jBReportarActionPerformed(java.awt.event.ActionEvent evt) {


this.jTASalida.setText("");
for(int i = 0; i < A.getCantidad(); i++)
{
this.jTASalida.append(""+A.getDatos(i)+"\n");
}
}

private void jBSalirActionPerformed(java.awt.event.ActionEvent evt) {


System.exit(0);

19
}

7. Agregue otro JPanel y realice la siguiente interfaz visual

Controles (Objetos) Name Text


JPanel jPanel2 Titulo de pestaña: Ordenamiento
ToolTipText: Ordenamiento
JLabel jJLabel2 Método de ordenación:
JComboBox jCTipoOrde Model: Burbuja, Shell, Quicksort
JButton jBOrdenar Ordenar

8. Codifique el JButton correspondiente


private void jBOrdenarActionPerformed(java.awt.event.ActionEvent evt) {
String tipo = String.valueOf(this.jCBTipoOrde.getSelectedItem());
if(tipo.compareTo("Burbuja")==0)
{
A.ordenaBurbuja();
this.jTASalida1.setText("");
this.jTASalida1.append("Ordenamiento burbuja\n");
Reporte(jTASalida1);
}
else if(tipo.compareTo("Shell") == 0)
{
A.ordenaShell();
this.jTASalida1.setText("");
this.jTASalida1.append("Ordenamiento Shell\n");
Reporte(jTASalida1);
}
if(tipo.compareTo("Quicksort")==0)
{
A.ordenaQuickSort(0, A.getCantidad()-1);
this.jTASalida1.setText("");
this.jTASalida1.append("Ordenamiento Quicksort\n");
Reporte(jTASalida1);
}
}

9. Agregue otro JPanel y realice la siguiente interfaz visual

20
Controles (Objetos) Name Text
JPanel jPanel3 Titulo de pestaña: Búsquedas
ToolTipText: Búsquedas
JLabel jJLabel3 Ingrese valor a buscar:
JLabel jJLabel4 Seleccione tipo de busqueda:
JTextField jTFValor
JComboBox jCTipoBus Model: Secuencial, Binaria
JButton jBBuscar Buscar

10. Codifique los siguientes JButton


private void jBBuscarActionPerformed(java.awt.event.ActionEvent evt) {
String tipo = String.valueOf(this.jCTipoBus.getSelectedItem());
double w;
int pos;
w = Double.parseDouble(this.jTFValor.getText());
if(tipo.compareTo("Secuencial")==0)
{
pos = A.buscaSecuencial(w);
if(pos!=-1)
this.jLMen.setText("Dato encontrado en la posición:"+pos);
else
this.jLMen.setText("Dato no encontrado");
}
else if(tipo.compareTo("Binaria") == 0)
{
A.ordenaBurbuja();
pos = A.buscaBinaria(w);
if(pos!=-1)
this.jLMen.setText("Dato encontrado en la posición:"+pos);
else
this.jLMen.setText("Dato no encontrado");
}
}

11. Agregue otro JPanel y diseñe la siguiente interfaz visual.

21
Controles (Objetos) Name Text
JPanel jPanel4 Titulo de pestaña: Inserción
ToolTipText: Inserción
JLabel jJLabel5 Ingrese elemento a insertar:
JLabel jJLabel6 Ingrese posición a insertar:
JTextField jTFEle
JTextField jTFPos
JTextArea jTASalida2
JButton jBInsertar Insertar

12. Codificar los siguientes JButton


private void jBInsertarActionPerformed(java.awt.event.ActionEvent evt) {
double x;
int pos;
x = Double.parseDouble(this.jTFEle.getText());
pos = Integer.parseInt(this.jTFPos.getText());
if(pos<0 || pos>A.getCantidad())
JOptionPane.showMessageDialog(null, "Posicion fuera de lugar", "Mensaje",
JOptionPane.ERROR_MESSAGE);
else
{
A.Inserta(x, pos);
this.jTASalida2.setText("");
Reporte(jTASalida2);
}
}

Controles (Objetos) Name Text

22
JPanel jPanel5 Titulo de pestaña: Eliminación
ToolTipText: Eliminación
JLabel jJLabel7 Ingrese elemento a eliminar:
JTextField jTFElem
JTextArea jTASalida3
JButton jBEliminar Eliminar

13. Codificar el siguiente JButton


private void jBEliminarActionPerformed(java.awt.event.ActionEvent evt) {
double w;
int pos=-1;
w = Double.parseDouble(this.jTFElem.getText());
pos = A.buscaSecuencial(w);
if(pos==-1)
JOptionPane.showMessageDialog(null, "Dato no existe", "Mensaje",
JOptionPane.ERROR_MESSAGE);
else
{
A.Elimina(pos);
Reporte(jTASalida3);
}
}

14. Ejecutar la aplicación

Ventana de Ingreso de datos Ventana de ordenamiento: Método Quicksort

23
Ventana de búsquedas, En el ejemplo, se realiza una búsqueda Binaria Ventana de inserción de datos

Ventana de eliminación de elementos

Conjuntos de Ejercicios propuestos No 5 de Arreglos Unidimensionales


1. Sea V un arreglo de N enteros. Diseñe una clase, con sus atributos y métodos para calcular:
a. El elemento máximo del arreglo
b. El elemento mínimo del arreglo
c. La suma de los elementos del arreglo
d. El producto de los elementos del arreglo
e. El promedio de los elementos del arreglo
f. La suma de las inversas de sus elementos
g. La suma de sus elementos impares
h. La suma de sus elementos, que ocupen posiciones pares en el arreglo
i. La suma de sus elementos cuyos números primos
j. La suma de sus elementos cuyos números son compuestos
k. Buscar si existen dos números primos gemelos. Es decir primos impares cuya diferencia es 2. Algunos
ejemplos de primos gemelos son: (3, 5), (5, 7), (11, 13) y (71, 73)
l. Insertar un elemento x en una posición i ingresada por teclado
m. Invertir el arreglo, de modo que el último elemento se convierta en el primero y así sucesivamente
n. Suprimir un elemento x del arreglo

2. Sea A y B un arreglo de N enteros. Realice funciones y/o procedimientos para calcular:


a. Formar un arreglo que contenga la unión de los elementos de los dos arreglos
b. Combinar los dos arreglos ordenados en un solo arreglo ordenado
c. Formar un arreglo que contenga la intersección de los elementos de los dos arreglos
d. Crear un arreglo que contenga la diferencia del arreglo A menos el B
e. Calcular el promedio de los elementos de A mayores que los de B
f. Reportar los elementos de B mayores que el promedio de los elementos de A

3. Hacer un programa para ingresar las calificaciones de N estudiantes obtenidas en un examen, calcular e imprimir
la nota promedio, así como cada calificación y la diferencia con la media.

4. Calcular el promedio de N valores almacenados en un vector. Determinar además cuantos son mayores que el
promedio, imprimir el promedio, el número de datos mayores que el promedio y una lista de valores mayores que
el promedio.

5. Almacenar N números en un vector, almacenarlos en otro vector en orden inverso al vector original e imprimir el
vector resultante.

6. Realice un programa que lea dos vectores A y B de N elementos cada uno (puede ser 20, por ejemplo) y multiplique
el primer elemento de A con el último elemento de B y luego el segundo elemento de A por él diecinueveavo
elemento de B y así sucesivamente hasta llegar al veinteavo elemento de A por el primer elemento de B. El
resultado de la multiplicación almacenarlo en un vector C.

24
7. Diseñe un programa que almacene en un vector A los 100 primeros números de la serie fibonacci. La serie de
Fibonacci es: 1, 1, 2, 3, 5, 8,... Es la suma de los dos números anteriores, excepto los dos primeros que son la
semilla.

8. Escribir un programa que lea una lista de N elementos enteros y a continuación realice las siguientes tareas:
a. Calcular el promedio de los elementos del vector
b. Encontrar el valor máximo y el valor mínimo, asimismo retornar la posición que ocupan.
c. Si la posición del valor máximo está entre 2 y N – 1, Reemplazar el valor máximo por la suma de los elementos
adyacentes.
d. Reportar la diferencia de cada elemento con el promedio calculado en la parte a.

9. Haga un programa que permita imprimir los números primos que se encuentran en un vector numérica, indicando
fila y columna. Asimismo reportar la suma de dichos números.

10. Hacer un programa para ingresar datos a un vector. Hacer un procedimiento que busque un dato ingresado por
teclado en dicho vector, a continuación deberá intercambiar los valores adyacentes a dicho dato. Dicho
procedimiento deberá prever que si el dato buscado en el vector está en la primera o última posición, no se podrá
intercambiar dichos elementos adyacentes.

11. Ingresar N elementos a los vectores A y B. Se pide hacer lo siguiente:


a. Listar los elementos de A mayores que los de B.
b. Encontrar la suma de los elementos de B mayores que los de A.
c. Encontrar la suma de los elementos de A mayores que el promedio de los de B.
12. Dado un arreglo V de N elementos enteros, buscar la cadena de M celdas consecutivas en este arreglo cuya suma
sea máxima (obviamente M < N).
13. Un científico esta preocupado por que tiene que sumar 2 números de 25 digitos cada uno; y no tiene calculadora
para almacenar esa cantidad de dígitos. Usted como programador deberá compadecerse y ayudar a dicho cientifico
a salir del apuro. Para tal efecto debe utilizar 2 vectores para almacenar la información y proceder luego a realizar
la suma respectiva. Se supone que cada dígito ira a una celda del vector. Si lo resuelven, contribuirán a que deje
de preocuparse y les de las gracias el aludido.

25
2) ARREGLOS BIDIMENSIONALES O MATRICES O TABLAS

Concepto: Una matriz es un arreglo de datos dispuestos en filas y columnas. Para identificar un elemento particular
de la tabla, deberemos especificar dos subíndices; el primero identifica la fila del elemento, y él segundo identifica la
columna del elemento.

La matriz es una estructura de datos estándar de almacenamiento de datos de cualquier lenguaje de programación.
Una matriz tiene su nombre, tal como las variables, y se accede mediante índices a los valores que se almacenan en
ellas.

Una matriz es una colección finita, homogénea y ordenada de elementos.


- Finita: Todo arreglo tiene un límite; es decir debe determinarse cual será el número máximo de elementos
que podrán formar parte del arreglo. Las matrices tienen un límite superior e inferior. El primer elemento de
una matriz tiene el índice 0 por defecto.
- Homogénea: Todos los elementos de un arreglo son del mismo tipo (Enteros, Reales, Etc.); excepto si los
tipos de datos de la matriz son Object, en este caso pueden entrar cualquier tipo de datos (Cadenas, números,
etc.).
- Ordenada: Se puede determinar cuál es el primer elemento, el segundo, el tercero…y el enésimo elemento.
Es decir que los elementos de la matriz son contiguos dentro de los límites establecidos.

𝐚[𝟎][𝟎] 𝐚[𝟎][𝟏] 𝐚[𝟎][𝟐]


𝐚[𝟏][𝟎] 𝐚[𝟏][𝟏] 𝐚[𝟏][𝟐]
M=
𝐚[𝟐][𝟎] 𝐚[𝟐][𝟏] 𝐚[𝟐][𝟐]
[𝐚[𝟑][𝟎] 𝐚[𝟑][𝟏] 𝐚[𝟑][𝟐]]

26
El arreglo contiene cuatro filas y tres columnas, por lo que se dice que se trata de un arreglo de 4 por 3. En general,
un arreglo con m filas y n columnas se llama un arreglo de m por n.
Cada uno de los elementos en el arreglo a está identificado por un nombre de elemento de la forma a[i][j]; a es el
nombre del arreglo, e i y j son los subíndices que identifican en forma única a cada elemento dentro de a.
Un arreglo de múltiple subíndice puede ser inicializado en su declaración en forma similar a un arreglo de un
subíndice. Por ejemplo, un arreglo de doble subíndice b[1][1] podría ser declarado e inicializado con
int b[1][1] = {{1,2}, {3,4}};
Partes de una Matriz: Son los componentes, los índices y el nombre del arreglo. Los componentes hacen referencia
a los elementos que forman el arreglo; es decir a los valores que se almacenan en cada una de las casillas del mismo.
Los índices permiten hacer referencia a los componentes del arreglo en forma individual; es decir distinguir entre los
elementos del mismo.

Arreglos Bidimensionales o Matrices en Java


Los arreglos en Java son dinámicos, pero no extensibles, lo cual significa que deben ser creados con el tamaño que
tendrán hasta el final de su vida.

Un arreglo se declara de la siguiente forma:

<tipo_dato> [][] <Identificador>;

O sea, para declarar, por ejemplo, un arreglo de números enteros utilizaremos la siguiente sentencia:

int [][] Arreglo;

Es importante notar que el arreglo aún no ha sido creado, sino meramente declarado. Para crear el arreglo (reservar su
memoria e inicializarlo) deberemos recurrir al operador new:

Arreglo = new int[10][10];

Este comportamiento debe comprenderse de esta forma: en Java todo es un objeto, y los objetos deben ser creados
mediante el operador new. El caso de los arreglos no es diferente, el tipo de datos del arreglo (int [][] en este caso) es
una clase y cada una de sus instancias debe ser creada explícitamente, el tamaño puede pensarse como un parámetro
al constructor de la clase.
A partir de este momento podemos utilizar Arreglo como un arreglo de cualquier otro lenguaje.
Una de las características que hacen de Java un entorno de programación seguro, y que se relaciona con el manejo de
los arreglos es que el lenguaje no permite la indexación de arreglos fuera de rango, o sea, una asignación de este tipo
generará una excepción:
Arreglo [25][25] = 1;
Otra forma de declararlos es la siguiente:

Tipo_dato nombre_array[][]=new tipo_dato[cantidad_filas][cantidad_columnas];

27
tipo nombre_array[][]={valores};

int matriz[][] = {{1, 2, 3}, {4, 5, 6}};

Uso de bucles para manipular matrices


Puede procesar eficientemente una matriz mediante bucles For anidados. Por ejemplo, estas instrucciones inicializan
cada elemento de M a un valor basándose en su ubicación en la matriz:

Operaciones con matrices:


a. Lectura y escritura de una matriz: La lectura de una matriz consiste en ingresar datos a la matriz.
Generalmente se hará por filas.
i. Ingreso de elemento a elemento

import javax.swing.JOptionPane;
public void setIngreso(int e)
{
if (j < c)
{
M[i][j]= e;
j++;
}
else
{
j=0;
i++;
M[i][j] = e;
j++;
}
k++;
if(k>=f*c)
JOptionPane.showMessageDialog(null,"Culmino con el ingreso de
datos","Mensaje",JOptionPane.INFORMATION_MESSAGE);
}

ii. Ingreso de datos aleatorios a una matriz


import javax.swing.JOptionPane;
import java.util.Random;
public void getIngresoAleatorio()
{
Random generator = new Random();
for(int i = 0; i < f; i++)
for(int j= 0; j < c; j++)
{
int r = generator.nextInt(100) + 1; //Genera números aleatorios entre 1 y 100
M[i][j] = r;
}
}
La escritura consiste en reportar los datos a la pantalla. Se utilizará bucles for.
b. Copia de matrices: Consiste en copiar los elementos de una matriz en otra matriz.
c. Suma de matrices: Consiste en sumar los elementos de dos matrices y almacenarlos en una tercera matriz.

public int getSuma()


{
int s=0;
for(i=0; i < f; i++)
for(j = 0 ; j < c; j++)
s = s + M[i][j];
return s;
}

d. Suma de la diagonal principal


public int getSumaDiagonalPrincipal()
{
int sd=0;
for(i=0; i < f; i++)
for(j = 0 ; j < c; j++)

28
if(i == j)
sd = sd + M[i][j];
return sd;
}

e. Máximo y mínimo de una matriz: Consiste en encontrar los valores máximos y mínimos de una matriz.
El siguiente código, retorna el máximo, asimismo asigna las posiciones respectivas a dos variables, declaradas en
la clase.

public int getMaximo()


{
int max=M[0][0];
posfil = poscol=0;
for(i=0; i < f; i++)
for(j = 0 ; j < c; j++)
if(M[i][j]>max)
{
max = M[i][j];
posfil= i;
poscol = j;
}
return max;
}

f. Multiplicación de matrices: Consiste en multiplicar los elementos de dos matrices para obtener una tercera
matriz.

public void setMultiplicacion()


{
int s=0;
for(i=0; i < n; i++)
for(j=0; j < n; j++)
{
s = 0;
for(k=0; k < n; k++)
s = s + A[i][k]*B[k][j]; //Multiplicamos la fila por la columna
C[i][j]= s; //La sumatoria de la multiplicación le asignamos a la matriz multiplicación
}
}

g. Ordenación de matrices: Consiste en ordenar los elementos de una matriz; dicho ordenamiento puede hacerse
por filas o por columnas.
Primero se debe copiar los elementos de la matriz a un vector, para ordenarlos utilizando cualquier método
aprendido en vectores; en seguida se copiará los datos ordenados del vector a la matriz.

h. Búsqueda: Consiste en buscar un elemento en una matriz y reportar la posición que ocupa.

public void getBuscar(int e)


{
posfil = -1;
poscol = -1;
for(int i = 0; i < f; i++)
for(int j= 0; j < c; j++)
{
if(M[i][j]==e)
{
posfil = i;
poscol = j;
break;
}
}
}

29
i. Eliminación de filas o columnas: Consiste en ingresar la posición de La fila o columna a eliminar en una
matriz.

public void setEliminaFila(int fil)


{
for(int i = fil; i < f; i++)
for( int j = 0; j < c; j++ )
M[i][j] = M[i+1][j];
f = f-1;
}

j. Inserción de filas o columnas en una matriz: Consiste en insertar una fila o columna en una matriz en una
posición indicada.

public void setInsertaFila(int fil)


{
for( int i = f+1; i > fil; i--)
for( int j = 0; j < c; j++ )
M[i][j] = M[i-1][j];
f = f+1;
for( j = 0; j < c; j++ )
M[fil][j] = Integer.parseInt(JOptionPane.showInputDialog("Ingrese elemento:"));
}

k. Traspuesta: La traspuesta de una matriz es la que se genera trasponiendo las filas en columnas o viceversa.

Contron JTable(Tablas)
Class JTable
• java.lang.Object
o java.awt.Component
▪ java.awt.Container
▪ javax.swing.JComponent
▪ javax.swing.JTable

Constructor Summary
Constructors
Constructor and Description
JTable()
Constructs a default JTable that is initialized with a default data model, a default column model, and a default selection model.
JTable(int numRows, int numColumns)
Constructs a JTable with numRows and numColumns of empty cells using DefaultTableModel.
JTable(Object[][] rowData, Object[] columnNames)
Constructs a JTable to display the values in the two dimensional array, rowData, with column names, columnNames.
JTable(TableModel dm)
Constructs a JTable that is initialized with dm as the data model, a default column model, and a default selection model.
JTable(TableModel dm, TableColumnModel cm)
Constructs a JTable that is initialized with dm as the data model, cm as the column model, and a default selection model.
JTable(TableModel dm, TableColumnModel cm, ListSelectionModel sm)
Constructs a JTable that is initialized with dm as the data model, cm as the column model, and sm as the selection model.
JTable(Vector rowData, Vector columnNames)
Constructs a JTable to display the values in the Vector of Vectors, rowData, with column names, columnName.

Method Summary
Methods
Modifier and Type Method and Description

30
addColumn(TableColumn aColumn) Appends aColumn to the end of the array of columns held by this
void
JTable's column model.
addColumnSelectionInterval(int index0, int index1) Adds the columns from index0 to index1,
void
inclusive, to the current selection.
void addNotify(): Calls the configureEnclosingScrollPane method.
addRowSelectionInterval(int index0, int index1) Adds the rows from index0 to index1, inclusive, to
void
the current selection.
changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend)
void
Updates the selection models of the table, depending on the state of the two flags: toggle and extend.
void clearSelection(): Deselects all selected columns and rows.
columnAdded(TableColumnModelEvent e) Invoked when a column is added to the table column
void
model.
columnAtPoint(Point point) Returns the index of the column that point lies in, or -1 if the result is not
int
in the range [0, getColumnCount()-1].
void columnMarginChanged(ChangeEvent e): Invoked when a column is moved due to a margin change.
void columnMoved(TableColumnModelEvent e): Invoked when a column is repositioned.
columnRemoved(TableColumnModelEvent e) Invoked when a column is removed from the table
void
column model.
columnSelectionChanged(ListSelectionEvent e) Invoked when the selection model of the
void
TableColumnModel is changed.
configureEnclosingScrollPane(): If this JTable is the viewportView of an enclosing JScrollPane (the
protected void usual situation), configure this ScrollPane by, amongst other things, installing the table's tableHeader as
the columnHeaderView of the scroll pane.
convertColumnIndexToModel(int viewColumnIndex) : Maps the index of the column in the view at
int
viewColumnIndex to the index of the column in the table model.
convertColumnIndexToView(int modelColumnIndex): Maps the index of the column in the table
int
model at modelColumnIndex to the index of the column in the view.
convertRowIndexToModel(int viewRowIndex) Maps the index of the row in terms of the view to the
int
underlying TableModel.
convertRowIndexToView(int modelRowIndex) Maps the index of the row in terms of the TableModel
int
to the view.
protected createDefaultColumnModel() Returns the default column model object, which is a
TableColumnModel DefaultTableColumnModel.
createDefaultColumnsFromModel() Creates default columns for the table from the data model using
void
the getColumnCount method defined in the TableModel interface.
protected TableModel createDefaultDataModel() Returns the default table model object, which is a DefaultTableModel.
protected void createDefaultEditors() Creates default cell editors for objects, numbers, and boolean values.
createDefaultRenderers() Creates default cell renderers for objects, numbers, doubles, dates,
protected void
booleans, and icons.
protected createDefaultSelectionModel() Returns the default selection model object, which is a
ListSelectionModel DefaultListSelectionModel.
protected
createDefaultTableHeader() Returns the default table header object, which is a JTableHeader.
JTableHeader
createScrollPaneForTable(JTable aTable)
static JScrollPane Deprecated.
As of Swing version 1.0.2, replaced by new JScrollPane(aTable).
void doLayout(): Causes this table to lay out its rows and columns.
editCellAt(int row, int column): Programmatically starts editing the cell at row and column, if those
boolean
indices are in the valid range, and the cell at those indices is editable.
editCellAt(int row, int column, EventObject e): Programmatically starts editing the cell at row and
boolean
column, if those indices are in the valid range, and the cell at those indices is editable.
void editingCanceled(ChangeEvent e): Invoked when editing is canceled.
void editingStopped(ChangeEvent e): Invoked when editing is finished.

31
AccessibleContext getAccessibleContext(): Gets the AccessibleContext associated with this JTable.
getAutoCreateColumnsFromModel() Determines whether the table will create default columns from
boolean
the model.
getAutoCreateRowSorter() Returns true if whenever the model changes, a new RowSorter should be
boolean
created and installed as the table's sorter; otherwise, returns false.
int getAutoResizeMode(): Returns the auto resize mode of the table.
TableCellEditor getCellEditor(): Returns the active cell editor, which is null if the table is not currently editing.
getCellEditor(int row, int column): Returns an appropriate editor for the cell specified by row and
TableCellEditor
column.
getCellRect(int row, int column, boolean includeSpacing) Returns a rectangle for the cell that lies at
Rectangle
the intersection of row and column.
getCellRenderer(int row, int column) Returns an appropriate renderer for the cell specified by this row
TableCellRenderer
and column.
boolean getCellSelectionEnabled() Returns true if both row and column selection models are enabled.
getColumn(Object identifier): Returns the TableColumn object for the column in the table whose
TableColumn
identifier is equal to identifier, when compared using equals.
getColumnClass(int column) Returns the type of the column appearing in the view at column position
Class<?>
column.
int getColumnCount(): Returns the number of columns in the column model.
getColumnModel(): Returns the TableColumnModel that contains all column information of this
TableColumnModel
table.
getColumnName(int column): Returns the name of the column appearing in the view at column
String
position column.
boolean getColumnSelectionAllowed(): Returns true if columns can be selected.
getDefaultEditor(Class<?> columnClass) Returns the editor to be used when no editor has been set in
TableCellEditor
a TableColumn.
getDefaultRenderer(Class<?> columnClass) Returns the cell renderer to be used when no renderer has
TableCellRenderer
been set in a TableColumn.
boolean getDragEnabled(): Returns whether or not automatic drag handling is enabled.
getDropLocation(): Returns the location that this component should visually indicate as the drop
JTable.DropLocation
location during a DnD operation over the component, or null if no location is to currently be shown.
DropMode getDropMode(): Returns the drop mode for this component.
int getEditingColumn(): Returns the index of the column that contains the cell currently being edited.
int getEditingRow() Returns the index of the row that contains the cell currently being edited.
Component getEditorComponent(): Returns the component that is handling the editing session.
getFillsViewportHeight(): Returns whether or not this table is always made large enough to fill the
boolean
height of an enclosing viewport.
Color getGridColor(): Returns the color used to draw grid lines.
Dimension getIntercellSpacing(): Returns the horizontal and vertical space between cells.
TableModel getModel(): Returns the TableModel that provides the data displayed by this JTable.
Dimension getPreferredScrollableViewportSize(): Returns the preferred size of the viewport for this table.
getPrintable(JTable.PrintMode printMode, MessageFormat headerFormat,
Printable
MessageFormat footerFormat): Return a Printable for use in printing this JTable.
int getRowCount(): Returns the number of rows that can be shown in the JTable, given unlimited space.
int getRowHeight(): Returns the height of a table row, in pixels.
int getRowHeight(int row): Returns the height, in pixels, of the cells in row.
int getRowMargin(): Gets the amount of empty space, in pixels, between cells.
boolean getRowSelectionAllowed(): Returns true if rows can be selected.
RowSorter<? extends
getRowSorter(): Returns the object responsible for sorting.
TableModel>
int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction)

32
Returns visibleRect.height or visibleRect.width, depending on this table's orientation.
getScrollableTracksViewportHeight(): Returns false to indicate that the height of the viewport does
boolean not determine the height of the table, unless getFillsViewportHeight is true and the preferred height of
the table is smaller than the viewport's height.
getScrollableTracksViewportWidth(): Returns false if autoResizeMode is set to
boolean AUTO_RESIZE_OFF, which indicates that the width of the viewport does not determine the width of
the table.
getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction)
int Returns the scroll increment (in pixels) that completely exposes one new row or column (depending on
the orientation).
int getSelectedColumn(): Returns the index of the first selected column, -1 if no column is selected.
int getSelectedColumnCount(): Returns the number of selected columns.
int[] getSelectedColumns(): Returns the indices of all selected columns.
int getSelectedRow(): Returns the index of the first selected row, -1 if no row is selected.
int getSelectedRowCount(): Returns the number of selected rows.
int[] getSelectedRows(): Returns the indices of all selected rows.
Color getSelectionBackground(): Returns the background color for selected cells.
Color getSelectionForeground(): Returns the foreground color for selected cells.
ListSelectionModel getSelectionModel(): Returns the ListSelectionModel that is used to maintain row selection state.
getShowHorizontalLines(): Returns true if the table draws horizontal lines between cells, false if it
boolean
doesn't.
boolean getShowVerticalLines(): Returns true if the table draws vertical lines between cells, false if it doesn't.
getSurrendersFocusOnKeystroke() Returns true if the editor should get the focus when keystrokes
boolean
cause the editor to be activated
JTableHeader getTableHeader(): Returns the tableHeader used by this JTable.
getToolTipText(MouseEvent event) Overrides JComponent's getToolTipText method in order to
String
allow the renderer's tips to be used if it has text set.
TableUI getUI(): Returns the L&F object that renders this component.
getUIClassID(): Returns the suffix used to construct the name of the L&F class used to render this
String
component.
boolean getUpdateSelectionOnSort(): Returns true if the selection should be updated after sorting.
Object getValueAt(int row, int column): Returns the cell value at row and column.
protected void initializeLocalVars(): Initializes table properties to their default values.
boolean isCellEditable(int row, int column): Returns true if the cell at row and column is editable.
isCellSelected(int row, int column): Returns true if the specified indices are in the valid range of rows
boolean
and columns and the cell at the specified position is selected.
isColumnSelected(int column): Returns true if the specified index is in the valid range of columns, and
boolean
the column at that index is selected.
boolean isEditing(): Returns true if a cell is being edited.
isRowSelected(int row) Returns true if the specified index is in the valid range of rows, and the row at
boolean
that index is selected.
moveColumn(int column, int targetColumn) Moves the column column to the position currently
void
occupied by the column targetColumn in the view.
protected String paramString(): Returns a string representation of this table.
prepareEditor(TableCellEditor editor, int row, int column): Prepares the editor by querying the data
Component
model for the value and selection state of the cell at row, column.
prepareRenderer(TableCellRenderer renderer, int row, int column): Prepares the renderer by querying
Component
the data model for the value and selection state of the cell at row, column.
print(): A convenience method that displays a printing dialog, and then prints this JTable in mode
boolean
PrintMode.FIT_WIDTH, with no header or footer text.
print(JTable.PrintMode printMode): A convenience method that displays a printing dialog, and then
boolean
prints this JTable in the given printing mode, with no header or footer text.

33
print(JTable.PrintMode printMode, MessageFormat headerFormat, MessageFormat footerFormat)
boolean A convenience method that displays a printing dialog, and then prints this JTable in the given printing
mode, with the specified header and footer text.
print(JTable.PrintMode printMode, MessageFormat headerFormat, MessageFormat footerFormat,
boolean showPrintDialog, PrintRequestAttributeSet attr, boolean interactive)
boolean
Prints this table, as specified by the fully featured print method, with the default printer specified as the
print service.
print(JTable.PrintMode printMode, MessageFormat headerFormat, MessageFormat footerFormat,
boolean boolean showPrintDialog, PrintRequestAttributeSet attr, boolean interactive, PrintService service)
Prints this JTable.
processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed)
protected boolean
Invoked to process the key bindings for ks as the result of the KeyEvent e.
void removeColumn(TableColumn aColumn): Removes aColumn from this JTable's array of columns.
removeColumnSelectionInterval(int index0, int index1): Deselects the columns from index0 to
void
index1, inclusive.
void removeEditor(): Discards the editor object and frees the real estate it used for cell rendering.
void removeNotify(): Calls the unconfigureEnclosingScrollPane method.
removeRowSelectionInterval(int index0, int index1): Deselects the rows from index0 to index1,
void
inclusive.
protected void resizeAndRepaint(): Equivalent to revalidate followed by repaint.
rowAtPoint(Point point): Returns the index of the row that point lies in, or -1 if the result is not in the
int
range [0, getRowCount()-1].
void selectAll(): Selects all rows, columns, and cells in the table.
setAutoCreateColumnsFromModel(boolean autoCreateColumnsFromModel)
void
Sets this table's autoCreateColumnsFromModel flag.
setAutoCreateRowSorter(boolean autoCreateRowSorter)
void
Specifies whether a RowSorter should be created for the table whenever its model changes.
void setAutoResizeMode(int mode): Sets the table's auto resize mode when the table is resized.
void setCellEditor(TableCellEditor anEditor): Sets the active cell editor.
setCellSelectionEnabled(boolean cellSelectionEnabled)
void
Sets whether this table allows both a column selection and a row selection to exist simultaneously.
setColumnModel(TableColumnModel columnModel): Sets the column model for this table to
void
newModel and registers for listener notifications from the new column model.
setColumnSelectionAllowed(boolean columnSelectionAllowed)
void
Sets whether the columns in this model can be selected.
setColumnSelectionInterval(int index0, int index1): Selects the columns from index0 to index1,
void
inclusive.
setDefaultEditor(Class<?> columnClass, TableCellEditor editor)
void
Sets a default cell editor to be used if no editor has been set in a TableColumn.
setDefaultRenderer(Class<?> columnClass, TableCellRenderer renderer)
void
Sets a default cell renderer to be used if no renderer has been set in a TableColumn.
void setDragEnabled(boolean b): Turns on or off automatic drag handling.
void setDropMode(DropMode dropMode): Sets the drop mode for this component.
void setEditingColumn(int aColumn): Sets the editingColumn variable.
void setEditingRow(int aRow): Sets the editingRow variable.
setFillsViewportHeight(boolean fillsViewportHeight)
void
Sets whether or not this table is always made large enough to fill the height of an enclosing viewport.
void setGridColor(Color gridColor): Sets the color used to draw grid lines to gridColor and redisplays.
setIntercellSpacing(Dimension intercellSpacing): Sets the rowMargin and the columnMargin -- the
void
height and width of the space between cells -- to intercellSpacing.
setModel(TableModel dataModel): Sets the data model for this table to newModel and registers with it
void
for listener notifications from the new data model.

34
setPreferredScrollableViewportSize(Dimension size): Sets the preferred size of the viewport for this
void
table.
setRowHeight(int rowHeight): Sets the height, in pixels, of all cells to rowHeight, revalidates, and
void
repaints.
void setRowHeight(int row, int rowHeight): Sets the height for row to rowHeight, revalidates, and repaints.
void setRowMargin(int rowMargin): Sets the amount of empty space between cells in adjacent rows.
setRowSelectionAllowed(boolean rowSelectionAllowed): Sets whether the rows in this model can be
void
selected.
void setRowSelectionInterval(int index0, int index1): Selects the rows from index0 to index1, inclusive.
void setRowSorter(RowSorter<? extends TableModel> sorter): Sets the RowSorter.
void setSelectionBackground(Color selectionBackground): Sets the background color for selected cells.
void setSelectionForeground(Color selectionForeground): Sets the foreground color for selected cells.
setSelectionMode(int selectionMode): Sets the table's selection mode to allow only single selections, a
void
single contiguous interval, or multiple intervals.
setSelectionModel(ListSelectionModel newModel): Sets the row selection model for this table to
void
newModel and registers for listener notifications from the new selection model.
void setShowGrid(boolean showGrid): Sets whether the table draws grid lines around cells.
setShowHorizontalLines(boolean showHorizontalLines): Sets whether the table draws horizontal lines
void
between cells.
setShowVerticalLines(boolean showVerticalLines): Sets whether the table draws vertical lines
void
between cells.
setSurrendersFocusOnKeystroke(boolean surrendersFocusOnKeystroke)
void Sets whether editors in this JTable get the keyboard focus when an editor is activated as a result of the
JTable forwarding keyboard events for a cell.
setTableHeader(JTableHeader tableHeader): Sets the tableHeader working with this JTable to
void
newHeader.
void setUI(TableUI ui): Sets the L&F object that renders this component and repaints.
setUpdateSelectionOnSort(boolean update): Specifies whether the selection should be updated after
void
sorting.
setValueAt(Object aValue, int row, int column): Sets the value for the cell in the table model at row
void
and column.
sizeColumnsToFit(boolean lastColumnOnly)
void Deprecated.
As of Swing version 1.0.3, replaced by doLayout().
void sizeColumnsToFit(int resizingColumn): Obsolete as of Java 2 platform v1.4.
sorterChanged(RowSorterEvent e): RowSorterListener notification that the RowSorter has changed in
void
some way.
tableChanged(TableModelEvent e): Invoked when this table's TableModel generates a
void
TableModelEvent.
unconfigureEnclosingScrollPane(): Reverses the effect of configureEnclosingScrollPane by replacing
protected void
the columnHeaderView of the enclosing scroll pane with null.
void updateUI(): Notification from the UIManager that the L&F has changed.
valueChanged(ListSelectionEvent e): Invoked when the row selection changes -- repaints to show the
void
new selection.

Class DefaultTableModel
java.lang.Object
javax.swing.table.AbstractTableModel
javax.swing.table.DefaultTableModel

Constructor Summary
Constructors

35
Constructor and Description
DefaultTableModel()
Constructs a default DefaultTableModel which is a table of zero columns and zero rows.
DefaultTableModel(int rowCount, int columnCount)
Constructs a DefaultTableModel with rowCount and columnCount of null object values.
DefaultTableModel(Object[][] data, Object[] columnNames)
Constructs a DefaultTableModel and initializes the table by passing data and columnNames to the setDataVector method.
DefaultTableModel(Object[] columnNames, int rowCount)
Constructs a DefaultTableModel with as many columns as there are elements in columnNames and rowCount of null object
values.
DefaultTableModel(Vector columnNames, int rowCount)
Constructs a DefaultTableModel with as many columns as there are elements in columnNames and rowCount of null object
values.
DefaultTableModel(Vector data, Vector columnNames)
Constructs a DefaultTableModel and initializes the table by passing data and columnNames to the setDataVector method.

Method Summary
Methods
Modifier and
Method and Description
Type
void addColumn(Object columnName): Adds a column to the model.
void addColumn(Object columnName, Object[] columnData): Adds a column to the model.
void addColumn(Object columnName, Vector columnData): Adds a column to the model.
void addRow(Object[] rowData): Adds a row to the end of the model.
void addRow(Vector rowData): Adds a row to the end of the model.
protected static
convertToVector(Object[] anArray): Returns a vector that contains the same objects as the array.
Vector
protected static
convertToVector(Object[][] anArray): Returns a vector of vectors that contains the same objects as the array.
Vector
int getColumnCount(): Returns the number of columns in this data table.
String getColumnName(int column): Returns the column name.
Vector getDataVector(): Returns the Vector of Vectors that contains the table's data values.
int getRowCount(): Returns the number of rows in this data table.
Object getValueAt(int row, int column): Returns an attribute value for the cell at row and column.
void insertRow(int row, Object[] rowData) Inserts a row at row in the model.
void insertRow(int row, Vector rowData) Inserts a row at row in the model.
boolean isCellEditable(int row, int column) Returns true regardless of parameter values.
moveRow(int start, int end, int to) Moves one or more rows from the inclusive range start to end to the to
void
position in the model.
void newDataAvailable(TableModelEvent event) Equivalent to fireTableChanged.
void newRowsAdded(TableModelEvent e) Ensures that the new rows have the correct number of columns.
void removeRow(int row) Removes the row at row from the model.
void rowsRemoved(TableModelEvent event) Equivalent to fireTableChanged.
void setColumnCount(int columnCount) Sets the number of columns in the model.
void setColumnIdentifiers(Object[] newIdentifiers) Replaces the column identifiers in the model.
void setColumnIdentifiers(Vector columnIdentifiers) Replaces the column identifiers in the model.
setDataVector(Object[][] dataVector, Object[] columnIdentifiers) Replaces the value in the dataVector
void
instance variable with the values in the array dataVector.
setDataVector(Vector dataVector, Vector columnIdentifiers) Replaces the current dataVector instance
void
variable with the new Vector of rows, dataVector.

36
void setNumRows(int rowCount) Obsolete as of Java 2 platform v1.3.
void setRowCount(int rowCount) Sets the number of rows in the model.
void setValueAt(Object aValue, int row, int column) Sets the object value for the cell at column and row.

APLICACIÓN CON OPERACIONES BASICAS CON MATRICES: LECTURA, ESCRITURA,


SUMAS, MAXIMOS, MINIMOS, BUSQUEDA, INSERCION E ELIMINACION FILAS,
MULTIPLICACION, ETC

Implementar una clase en Java, con sus atributos y métodos, de tal manera que nos permita indicar la cantidad de filas
y columnas de una matriz, ingresar sus elementos manualmente y aleatoriamente, sumar sus elementos, encontrar el
valor máximo y reportar su posición donde se encuentra, sumar los elementos de la diagonal principal, encontrar el
promedio de los elementos de la matriz la multiplicación de dos matrices, eliminación de filas, inserción de columnas
y búsquedas de datos, etc.

a. Crear un nuevo proyecto con el nombre JAMatrices.


b. Crear una clase con el nombre CMatrices, con sus atributos y métodos respectivos:

import javax.swing.JOptionPane;
import java.util.Random;
public class CMatrices {
int [][]M;
int [][]A;
int [][]B;
int [][]C;
int f, c, k, posfil, poscol;
int i, j, n;

public CMatrices()
{
M = new int[100][100];
A = new int[100][100];
B = new int[100][100];
C = new int[100][100];
f = c = 0;
i = j = 0;
k = 0;
}
public void setFilasColumnas(int c1, int f1)
{
f = f1;
c = c1;
}
public void setFilasColumnas1(int n1)
{
n = n1;
}
public void setIngreso(int e)
{
if (j < c)
{
M[i][j]= e;
j++;
}
else
{
j=0;
i++;
M[i][j] = e;
j++;
}
k++;
37
if(k>=f*c)
JOptionPane.showMessageDialog(null,"Culmino con el ingreso de datos","Mensaje", JOptionPane.INFORMATION_MESSAGE);
}
public void getIngresoAleatorio()
{
Random generator = new Random();
for(int i = 0; i < f; i++)
for(int j= 0; j < c; j++)
{
int r = generator.nextInt(100) + 1; //Genera números aleatorios entre 1 y 100
M[i][j] = r;
}
}
public int getReporte(int [][]M1, int i1, int j1)
{
return M1[i1][j1];

}
public int getSuma()
{
int s=0;
for(i=0; i < f; i++)
for(j = 0 ; j < c; j++)
s = s + M[i][j];
return s;
}
public int getSumaDiagonalPrincipal()
{
int sd=0;
for(i=0; i < f; i++)
for(j = 0 ; j < c; j++)
if(i == j)
sd = sd + M[i][j];
return sd;
}
public int getMaximo()
{
int max=M[0][0];
posfil = poscol=0;
for(i=0; i < f; i++)
for(j = 0 ; j < c; j++)
if(M[i][j]>max)
{
max = M[i][j];
posfil= i;
poscol = j;
}
return max;
}
public void setMultiplicacion()
{
int s=0;
for(i=0; i < n; i++)
for(j=0; j < n; j++)
{
s = 0;
for(k=0; k < n; k++)
s = s + A[i][k]*B[k][j]; //Multiplicamos la fila por la columna
C[i][j]= s; //La sumatoria de la multiplicación le asignamos a la matriz multiplicación
}
}
public void getBuscar(int e)
{

38
posfil = -1;
poscol = -1;
for(int i = 0; i < f; i++)
for(int j= 0; j < c; j++)
{
if(M[i][j]==e)
{
posfil = i;
poscol = j;
break;
}
}
}
public void setEliminaFila(int fil)
{
for(int i = fil; i < f; i++)
for( int j = 0; j < c; j++ )
M[i][j] = M[i+1][j];
f = f-1;
}
public void setInsertaFila(int fil)
{
for( int i = f+1; i > fil; i--)
for( int j = 0; j < c; j++ )
M[i][j] = M[i-1][j];
f = f+1;
for( j = 0; j < c; j++ )
M[fil][j] = Integer.parseInt(JOptionPane.showInputDialog("Ingrese elemento:"));
}
}

c. Agregar un formulario JFrame con el nombre JFMatrices.


d. Agregar un panel con pestañas (JTabbedPane).

e. Después de haber agregado el panel con pestañas, haga clic botón derecho, seleccione la opción Añadir paleta,
Contenedores Swing, Panel. Como se aprecia en la figura siguiente:

39
f. Después de haber agregado el primer Panel, el diseño del formulario debe quedar así:

g. Continúe agregando más Paneles hasta tener unos 5 como se aprecia en la figura siguiente:

h. Cambiar el título de la pestaña, para esto deben hacer lo siguiente:

40
Debe cliquear acá en la pestaña y en
el centro del panel para colocar el
título de la pestaña y para colocar los
controles de la interfaz visual

i. Después de haber cambiado el titulo de los Panel, debe quedar así el diseño respectivo

j. Crear la interfaz visual para este Panel1 Ingreso de Datos

Controles (Objetos) Propiedades Valor


JPanel1 toolTipText Ingreso de datos de la matriz
Título de pestaña Ingreso datos
JButton1 Nombre jBFC
Text Ingreso filas y columnas
JButton2 Nombre jBDatos
Text Ingreso datos
JButton3 Nombre jBDatosA
Text Ingreso datos aleatorios

k. Crear la interfaz visual siguiente, para el Panel2 Ingreso de Datos


41
Controles (Objetos) Propiedades Valor
JPanel2 toolTipText Reporte de datos de la matriz
Título de pestaña Reporte datos
JButton4 Nombre jBReportar
Text Ver Matriz
JTable1 Nombre jTSalida //Tabla
toolTipText Reporte de datos de la matriz

Al agregar una Tabla, inicialmente se ve así:

Haga clic en la propiedad model para borrar los títulos de las columnas

Seleccione la columna y
haga clic en el botón de
comando eliminar

Finalmente la tabla quedara como la que se muestra a continuación, finalmente de clic en aceptar.

42
l. Crear la interfaz visual siguiente, para el Panel3 Ingreso de Datos

Controles (Objetos) Propiedades Valor


JPanel3 toolTipText Operaciones varias
Titulo de pestaña Operaciones varias
JLabel1 Nombre jLMax
JLabel2 Nombre jLSum
JLabel3 Nombre jLSDP
JButton5 Nombre jBMaximo
Text Maximo
JButton6 Nombre jBSuma
Text Suma
JButton7 Nombre jBSumaDP
Text Suma Diag. Prin.

m. Crear la interfaz visual siguiente, para el Panel4 Ingreso de Datos

43
Controles (Objetos) Propiedades Valor
JPanel4 toolTipText Búsquedas, eliminaciones, inserciones
Titulo de pestaña Inserciones y otros
JLabel4 Text Ingrese valor a buscar:
JLabel5 Text Ingrese posición de fila a eliminar
JLabel6 Text Ingrese posición de fila a insertar
JButton6 Nombre jBBuscar
Text BUscar
JButton7 Nombre jBEliminaFila
Text Elimina fila
JButton8 Nombre jBInsertaFila
Text Insertar fila
JTable2 Nombre jTSalida1 //Tabla
toolTipText Reporte de datos de la matriz modificada
JTextField1 Nombre jTFB
Enabled Desmarcar casillero
JTextField2 Nombre jTFEF
Enabled Desmarcar casillero
JTextField3 Nombre jTFFI
Enabled Desmarcar casillero
JRadioButton1 Nombre jRBBuscar //Botón de opción
Text Valor a buscar
buttonGroup buttonGroup1
JRadioButton2 Nombre jRBEliminar
Text Eliminar filas
buttonGroup buttonGroup1
JRadioButton2 Nombre jRBInsertar
Text Insertar filas
buttonGroup buttonGroup1

ButtonGroup1 //Grupo de botones

44
Controles (Objetos) Propiedades Valor
JPanel4 toolTipText Multiplicación de matrices
Titulo de pestaña Reporte datos
JButton9 Nombre jBDimension
Text Dimensión matriz
JButton10 Nombre jBIngreso1
Text Ingreso datos
JButton11 Nombre jBMultiplica
Text Multiplicación
JButton12 Nombre jBReportes
Text Reportes
JTable3 Nombre jTSalidaa
toolTipText Datos de la matriz A
JTable4 Nombre jTSalidab
toolTipText Datos de la matriz B
JTable5 Nombre jTSalidac
toolTipText Datos de la matriz C
JLabel7 Text Matriz A
JLabel8 Text Matriz B
JLabel9 Text Matriz Multiplicación

n. Hacer referencia a las siguientes librerías de Java


import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import java.util.Vector;
import java.util.Random;
import java.util.*;

o. Crear los siguientes metodos


public void getReportar(int [][]M1, JTable jTSalida1)
{
Vector Fila = new Vector();
for(int i = 0; i<obj.f; i++)
{
Vector Campos = new Vector();
for(int j = 0; j < obj.c; j++)
Campos.addElement(M1[i][j]);
Fila.addElement(Campos);
}
Vector Cabecera = new Vector(obj.c);
for(int j=0; j < obj.c; j++)
Cabecera.addElement(j);

45
DefaultTableModel model = new DefaultTableModel (Fila, Cabecera);
jTSalida1.setModel(model);
}
public void getReportar1(int [][]M1, JTable jTSalida1)
{
Vector Fila = new Vector();
for(int i = 0; i<obj.n; i++)
{
Vector Campos = new Vector();
for(int j = 0; j < obj.n; j++)
Campos.addElement(M1[i][j]);
Fila.addElement(Campos);
}
Vector Cabecera = new Vector(obj.n);
for(int j=0; j < obj.n; j++)
Cabecera.addElement(j);
DefaultTableModel model = new DefaultTableModel (Fila, Cabecera);
jTSalida1.setModel(model);
}

p. Al final de la declaración de objetos, realice la siguiente declaración:


CMatrices obj = new CMatrices();

q. Codificar los siguientes jButton


private void jBFCActionPerformed(java.awt.event.ActionEvent evt) {
int fila, columna;
String f1, c1;
f1 = JOptionPane.showInputDialog("Ingrese cantidad de filas:");
c1 = JOptionPane.showInputDialog("Ingrese cantidad de columnas:");
fila = Integer.parseInt(f1);
columna = Integer.parseInt(c1);
obj.setFilasColumnas(fila, fila);
}

private void jBDatosActionPerformed(java.awt.event.ActionEvent evt) {


String datos;
int e;
for(int i = 0; i < obj.f; i++)
for(int j= 0; j < obj.c; j++)
{
datos = JOptionPane.showInputDialog("Ingrese elemento:M["+i+"]"+"["+j+"]==>:");
e = Integer.parseInt(datos);
obj.setIngreso(e);
}
}

private void jBReportarActionPerformed(java.awt.event.ActionEvent evt) {


getReportar(obj.M, jTSalida);
}

private void jBDatosAActionPerformed(java.awt.event.ActionEvent evt) {


obj.getIngresoAleatorio();
}

private void jBMaximoActionPerformed(java.awt.event.ActionEvent evt) {


int max = obj.getMaximo();
this.jLMax.setText("El valor maximo :"+max+" Pos. fila:"+obj.posfil+" pos. col.:"+obj.poscol);
}

private void jBSumaActionPerformed(java.awt.event.ActionEvent evt) {


int suma = obj.getSuma();

46
this.jLSum.setText("La suma de los elementos de la matriz es:"+suma);
}

private void jBSumaDPActionPerformed(java.awt.event.ActionEvent evt) {


int sd = obj.getSumaDiagonalPrincipal();
this.jLSDP.setText("La suma de la diagonal principal es:"+sd);
}
private void jBIngreso1ActionPerformed(java.awt.event.ActionEvent evt) {
Random generator = new Random();
for(int i = 0; i < obj.n; i++) //Ingreso de datos para A
for(int j= 0; j < obj.n; j++)
{
int r = generator.nextInt(100) + 1; //Genera numeros aleatorios entre 1 y 100
obj.A[i][j] = r;
}
for(int i = 0; i < obj.n; i++) //Ingreso de datos para B
for(int j= 0; j < obj.n; j++)
{
int r = generator.nextInt(100) + 1;
obj.B[i][j] = r;
}
}

private void jBMultiplicaActionPerformed(java.awt.event.ActionEvent evt) {


obj.setMultiplicacion();
}

private void jBDimensionActionPerformed(java.awt.event.ActionEvent evt) {


int n1;
n1 = Integer.parseInt(JOptionPane.showInputDialog("Ingrese n para dimensionar matriz:"));
obj.setFilasColumnas1(n1);
}

private void jBReportesActionPerformed(java.awt.event.ActionEvent evt) {


getReportar1(obj.A, jTSalidaA);
getReportar1(obj.B, jTSalidaB);
getReportar1(obj.C, jTSalidaC);
}

private void jRBBuscarActionPerformed(java.awt.event.ActionEvent evt) {


this.jTFB.setEnabled(true);
this.jBBuscar.setEnabled(true);
}

private void jRBEliminarActionPerformed(java.awt.event.ActionEvent evt) {


this.jTFEF.setEnabled(true);
this.jBEliminaFila.setEnabled(true);
}

private void jRBInsertarActionPerformed(java.awt.event.ActionEvent evt) {


this.jBInsertaFila.setEnabled(true);
this.jTFFI.setEnabled(true);
}

private void jBBuscarActionPerformed(java.awt.event.ActionEvent evt) {


int e = Integer.parseInt(this.jTFB.getText());
obj.getBuscar(e);
if(obj.posfil!=-1 && obj.f !=-1)
JOptionPane.showMessageDialog(null,"Valor encontrado en fila:"+obj.posfil+" Columna:"+obj.poscol,
"Mensaje de busqueda",JOptionPane.INFORMATION_MESSAGE);
else

47
JOptionPane.showMessageDialog(null,"Valor no encontrado","Mensaje de busqueda",
JOptionPane.INFORMATION_MESSAGE);
}

private void jBEliminaFilaActionPerformed(java.awt.event.ActionEvent evt) {


int fila = Integer.parseInt(this.jTFEF.getText());
if(fila < 0 || fila > obj.f)
JOptionPane.showMessageDialog(null, "Posicion fuera de lugar","Mensaje de Eliminacion",
JOptionPane.ERROR_MESSAGE);
else
{
obj.setEliminaFila(fila);
getReportar(obj.M, jTSalida1);
}
}

private void jBInsertaFilaActionPerformed(java.awt.event.ActionEvent evt) {


int fila = Integer.parseInt(this.jTFFI.getText());
if(fila < 0 || fila > obj.f)
JOptionPane.showMessageDialog(null, "Posicion fuera de lugar","Mensaje de Eliminacion",
JOptionPane.ERROR_MESSAGE);
else
{
obj.setInsertaFila(fila);
getReportar(obj.M, jTSalida1);
}
}
r. Ejecutar la aplicación

Ventana donde nos pide la cantidad de filas y columnas que tendrá la matriz.

48
Ventana donde se ingresa elemento a elemento a la matriz.

Ventana que nos indica que ya culminamos el ingreso de datos

Ventana, indicando el valor máximo encontrado y la posición de la fila y columna. La suma de los
elementos de la matriz, y la suma de la diagonal principal.

49
Ventana que muestra la búsqueda de elementos en una matriz

Ventana que muestra la eliminación de la fila No 1

Ventana que muestra los elementos que se ingresan para insertar en la fila No 2 de la matriz

50
Ventana que muestra los datos de la matriz con la fila insertada

Ventana que muestra la multiplicación de dos matrices.

Conjuntos de Ejercicios propuestos No 6 de Arreglos Bidimensionales o Matrices


1. Elaborar una aplicación que llene una matriz por columnas y la imprima por filas.
2. Para el ejercicio anterior, encuentre el elemento mayor y el menor, así como sus posiciones, en caso de
que alguno de los elementos (mayor y/o menor) esté varias veces en la matriz, indíquele esta situación
al usuario mediante un mensaje.
3. Elabore una aplicación que convierta una matriz (llena), en un arreglo unidimensional. La conversión
debe hacerse por columnas, es decir, mover la primera columna al vector, a continuación la segunda
columna y así sucesivamente. Imprima ambos arreglos.
4. Elabore una aplicación que llene una matriz de un tamaño definido por el usuario. Luego intercambie
el contenido de la primera y la última columna, de la segunda y la penúltima y así hasta completar
cambios que den una matriz con columnas invertidas. Imprima ambas matrices.
5. Realice una aplicación similar a la anterior, pero intercambiando filas.
6. Elabore una aplicación que llene una matriz cuadrada, la magnitud y los datos los ingresa el usuario,
luego averigüe si es simétrica, es decir, si todos los pares de elementos equidistantes
perpendicularmente de la diagonal principal son iguales.
7. En las elecciones para alcalde de un pueblo, se han presentado tres candidatos (A, B, C). el pueblito
está dividido en 5 zonas de votación.
El reporte de votos de las zonas se recibe en orden: primero la zona 1, la 2, etc. Elabore una aplicación
que:
✓ Forme una matriz de 5 filas y 3 columnas que contenga, en cada fila, los votos reportados por las zonas
para cada uno de los tres candidatos.
✓ Encuentre el total de votos obtenidos por cada candidato y el porcentaje que éste representa.
✓ Escriba un mensaje declarando ganador a un candidato, si éste obtuvo más del 50% de la votación, en
caso de “empate”, notifíquelo mediante un mensaje.
8. Elabore una aplicación que forme una matriz de orden NxM y la llene de datos enteros, (toda esta
información la proporciona el usuario), a continuación obtenga e imprima:
51
✓ Suma de cada fila impar (1,3,5,etc)
✓ Producto de la diagonal secundaria
✓ Número de valores iguales a cero
✓ Suma de todos los elementos de las columnas pares
9. Hacer un programa para ingresar datos a una matriz cuadrada y se pide que haga lo siguiente:
✓ Imprimir solo las diagonales como matriz, el resto de datos debe reportarse como ceros.
✓ Intercambiar las diagonales.
✓ Invertir las diagonales.
✓ Encontrar el mayor de los elementos de la matriz triangular inferior.
✓ El promedio de los elementos de la matriz triangular superior.
✓ Imprimir solo los elementos que están encima y debajo de la diagonal principal.
✓ Imprimir solo los elementos que están debajo de la diagonal secundaria.
✓ Elimine una fila y columna de la matriz.
✓ Eliminar la diagonal principal.
10. Hacer un programa para que ingrese datos a una matriz en forma aleatoria. Luego debe ordenar
dichos elementos por filas y luego por columnas.
11. Hacer un programa para ingresar la serie de Fibonacci en una matriz, Dicho ingreso deberá hacerlo
por filas en una matriz cuadrada.
Ejemplo
1 1 2 3
5 8 13 21
34 55 89 144
233 377 610 987

12. Hacer un programa para ingresar las tripletas pitagóricas encontradas del 1 al 100 en una matriz de 3 columnas
y el numero de filas dependerá de las tripletas encontradas, y realizar el reporte respectivo. Una tripleta
pitagórica debe cumplir z2 = x2 + y2
Ejemplo
3 4 5
5 12 13
… … …
65 72 97

13. Hacer un programa para ingresar números aleatorios a dos matrices A y B de tamaño n x m. Genere una tercera
Matriz C, con la suma de los datos de las matrices A y B mas el residuo de la división de dichas matrices y
reportelos. Si el elemento de la matriz C, termina en:
0, 1, 2 Eleve al cuadrado los elementos de la matriz A y reportelos
3,4,5 Busque los números primos de la Matriz B y reportelos
6,7,8 Intercambie los elementos de la Matriz A y B y reportelos
9 Reemplace los números múltiplos de 5 de la matriz A por 99 y reportelo

52

También podría gustarte