Sistemas

Sistemas

jueves, 17 de marzo de 2011

14-10 Matrices irregulares

Java nos permite crear matrices irregulares. Se dice que una matriz es irregular si la cantidad de elementos de cada fila varía. Luego podemos imaginar una matriz irregular:

matriz irregular
 
Como podemos ver la fila cero tiene reservado dos espacios, la fila uno reserva cuatro espacios y la última fila reserva espacio para tres componentes.

Para crear la matriz irregular del gráfico:
La declaración es la misma que para matrices regulares:
int [][] mat;

Primero creamos la cantidad de filas dejando vacío el espacio que indica la cantidad de columnas:
mat=new int[3][];

Luego debemos ir creando cada fila de la matriz indicando la cantidad de elementos de la respectiva fila:
mat[0]=new int[2];
mat[1]=new int[4];
mat[2]=new int[3];

Luego la forma para acceder a sus componentes es similar a las matrices regulares, siempre teniendo en cuenta y validando que exista dicha componente:
mat[0][0]=120;

Dará un error si queremos cargar la tercer componente de la fila cero (esto debido a que no existe):
mat[0][2]=230;

Luego si queremos saber la cantidad de filas que tiene la matriz:
Sytem.out.println(mat.length);

Si queremos saber la cantidad de elementos de una determinada fila:
Sytem.out.println("Cantidad de elementos de la fila 0:"+mat[0].length);
Sytem.out.println("Cantidad de elementos de la fila 1:"+mat[1].length);
Sytem.out.println("Cantidad de elementos de la fila 2:"+mat[2].length);

Problema 1:

Confeccionaremos un programa que permita crear una matriz irregular y luego imprimir la matriz en forma completa.

Programa:

import java.util.Scanner;
public class MatrizIrregular1 {
    private Scanner teclado;
    private int[][] mat;
    
    public void cargar() {
        teclado=new Scanner(System.in);
        System.out.print("Cuantas fila tiene la matriz:");
        int filas=teclado.nextInt();
        mat=new int[filas][];
        for(int f=0;f<mat.length;f++) {
            System.out.print("Cuantas elementos tiene la fila " + f + ":");
            int elementos=teclado.nextInt();
            mat[f]=new int[elementos];            
            for(int c=0;c<mat[f].length;c++) {
                System.out.print("Ingrese componente:");
                mat[f][c]=teclado.nextInt();
            }
        }
    }
    
    public void imprimir() {
        for(int f=0;f<mat.length;f++) {
            for(int c=0;c<mat[f].length;c++) {
                System.out.print(mat[f][c]+" ");
            }
            System.out.println();
        }
    }
    
    public static void main(String[] ar) {
        MatrizIrregular1 ma=new MatrizIrregular1();
        ma.cargar();
        ma.imprimir();
    }   
}

Primero creamos la cantidad de filas que tendrá la matriz (en los corchetes para las columnas no disponemos valor):
System.out.print("Cuantas fila tiene la matriz:");
        int filas=teclado.nextInt();
        mat=new int[filas][];

Dentro del primer for pedimos que ingrese la cantidad de elementos que tendrá cada fila y utilizamos el operador new nuevamente, pero en este caso se están creando cada fila de la matriz (Java trata a cada fila como un vector):
for(int f=0;f<mat.length;f++) {
            System.out.print("Cuantas elementos tiene la fila " + f + ":");
            int elementos=teclado.nextInt();
            mat[f]=new int[elementos];            

Dentro del for interno hacemos la carga de las componentes propiamente dicho de la matriz (podemos ir cargando cada fila a medida que las vamos creando):
for(int c=0;c<mat[f].length;c++) {
                System.out.print("Ingrese componente:");
                mat[f][c]=teclado.nextInt();
            }

Luego imprimimos la matriz en forma completa teniendo cuidado las condiciones que disponemos en cada for.
El primer for se repite tantas veces como filas tiene la matriz: f<mat.length y
el for interno se repite tantas veces como elementos tiene la fila que estamos procesando c<mat [f].length:
for(int f=0;f<mat.length;f++) {
            for(int c=0;c<mat[f].length;c++) {
                System.out.print(mat[f][c]+" ");
            }
            System.out.println();
        }

Problemas propuestos

  1. Confeccionar una clase para administrar una matriz irregular de 5 filas y 1 columna la primer fila, 2 columnas la segunda fila y así sucesivamente hasta 5 columnas la última fila (crearla sin la intervención del operador)
    Realizar la carga por teclado e imprimir posteriormente.
  2. Confeccionar una clase para administrar los días que han faltado los 3 empleados de una empresa.
    Definir un vector de 3 elementos de tipo String para cargar los nombres y una matriz irregular para cargar los días que han faltado cada empleado (cargar el número de día que faltó)
    Cada fila de la matriz representan los días de cada empleado.
    Mostrar los empleados con la cantidad de inasistencias.
    Cuál empleado faltó menos días.

14-9 Matrices y vectores paralelos

Dependiendo de la complejidad del problema podemos necesitar el empleo de vectores y matrices paralelos.

Problema 1:

Se tiene la siguiente información:

· Nombres de 4 empleados.
· Ingresos en concepto de sueldo, cobrado por cada empleado, en los últimos 3 meses.
Confeccionar el programa para:

a) Realizar la carga de la información mencionada.
b) Generar un vector que contenga el ingreso acumulado en sueldos en los últimos 3 meses para cada empleado.
c) Mostrar por pantalla el total pagado en sueldos a todos los empleados en los últimos 3 meses
d) Obtener el nombre del empleado que tuvo el mayor ingreso acumulado
vectores y matrices paralelos

Programa:

import java.util.Scanner;
public class Matriz9 {
    private Scanner teclado;
    private String[] empleados;
    private int[][] sueldos;
    private int[] sueldostot;
    
    public void cargar() {
        teclado=new Scanner(System.in);
        empleados=new String[4];
        sueldos=new int[4][3];
        for(int f=0;f<empleados.length;f++){
            System.out.print("Ingrese el nombre del empleado:");
            empleados[f]=teclado.next();
            for(int c=0;c<sueldos[f].length;c++) {
                System.out.print("Ingrese sueldo:");
                sueldos[f][c]=teclado.nextInt();
            }
        }
    }
    
    public void calcularSumaSueldos() {
     sueldostot=new int[4];
        for(int f=0;f<sueldos.length;f++) {
          int suma=0;
          for(int c=0;c<sueldos[f].length;c++) {
              suma=suma+sueldos[f][c];
          }
          sueldostot[f]=suma;
        }
    }
    
    public void imprimirTotalPagado() {
     System.out.println("Total de sueldos pagados por empleado.");
        for(int f=0;f<sueldostot.length;f++) {
            System.out.println(empleados[f]+" - "+sueldostot[f]);
        }
    }
    
    public void empleadoMayorSueldo() {
        int may=sueldostot[0];
        String nom=empleados[0];
        for(int f=0;f<sueldostot.length;f++) {
            if (sueldostot[f]>may) {
                may=sueldostot[f];
                nom=empleados[f];
            }
        }
        System.out.println("El empleado con mayor sueldo es "+ nom + " que tiene un sueldo de "+may);
    }
    
    public static void main(String[] ar){
        Matriz9 ma=new Matriz9();
        ma.cargar();
        ma.calcularSumaSueldos();
        ma.imprimirTotalPagado();
        ma.empleadoMayorSueldo();
    }
}

Para resolver este problema lo primero que hacemos es definir una matriz donde se almacenarán los sueldos mensuales de cada empleado, un vector de tipo String donde almacenaremos los nombre de cada empleado y finalmente definimos un vector paralelo a la matriz donde almacenaremos la suma de cada fila de la matriz:

private String[] empleados;
    private int[][] sueldos;
    private int[] sueldostot;

En el método de cargar inicializamos el vector con los nombres de los empleados y la matriz paralela donde se almacenan los últimos tres sueldos (previo a cargar procedemos a crear el vector y la matriz):

empleados=new String[4];
        sueldos=new int[4][3];
        for(int f=0;f<empleados.length;f++){
            System.out.print("Ingrese el nombre del empleado:");
            empleados[f]=teclado.next();
            for(int c=0;c<sueldos[f].length;c++) {
                System.out.print("Ingrese sueldo:");
                sueldos[f][c]=teclado.nextInt();
            }
        }

El método sumar sueldos crea el vector donde se almacenará la suma de cada fila de la matriz. Mediante dos for recorremos toda la matriz y sumamos cada fila:

sueldostot=new int[4];
        for(int f=0;f<sueldos.length;f++) {
          int suma=0;
          for(int c=0;c<sueldos[f].length;c++) {
              suma=suma+sueldos[f][c];
          }
          sueldostot[f]=suma;
        }

El método imprimirTotalPagado tiene por objetivo mostrar los dos vectores (el de nombre de los empleados y el que almacena la suma de cada fila de la matriz):

for(int f=0;f<sueldostot.length;f++) {
            System.out.println(empleados[f]+" - "+sueldostot[f]);
        }

Por último para obtener el nombre del empleado con mayor sueldo acumulado debemos inicializar dos variables auxiliares con el primer elemento del vector de empleados y en otra auxiliar guardamos la primer componente del vector sueldostot:

int may=sueldostot[0];
        String nom=empleados[0];
        for(int f=0;f<sueldostot.length;f++) {
            if (sueldostot[f]>may) {
                may=sueldostot[f];
                nom=empleados[f];
            }
        }
        System.out.println("El empleado con mayor sueldo es "+ nom + " que tiene un sueldo de "+may);

Problemas propuestos

  1. Se desea saber la temperatura media trimestral de cuatro paises. Para ello se tiene como dato las temperaturas medias mensuales de dichos paises.
    Se debe ingresar el nombre del país y seguidamente las tres temperaturas medias mensuales.
    Seleccionar las estructuras de datos adecuadas para el almacenamiento de los datos en memoria.
    a - Cargar por teclado los nombres de los paises y las temperaturas medias mensuales.
    b - Imprimir los nombres de las paises y las temperaturas medias mensuales de las mismas.
    c - Calcular la temperatura media trimestral de cada país.
    c - Imprimr los nombres de las provincias y las temperaturas medias trimestrales.
    b - Imprimir el nombre de la provincia con la temperatura media trimestral mayor.

martes, 8 de marzo de 2011

14-8 Matrices (cantidad de filas y columnas)

Como hemos visto para definir y crear la matriz utilizamos la siguiente sintaxis:
int[][] mat;

Creación:
mat=new int[3][4];

Como las matrices son objetos en Java disponemos por un lado del atributo length que almacena la cantidad de filas de la matriz:
System.out.println("Cantidad de filas de la matriz:" + mat.length);

También podemos preguntarle a cada fila de la matriz la cantidad de elementos que almacena:
System.out.println("Cantidad de elementos de la primer fila:" + mat[0].length);

Problema 1:

Crear una matriz de n * m filas (cargar n y m por teclado) Imprimir la matriz completa y la última fila.

Programa:

import java.util.Scanner;
public class Matriz5 {
    private Scanner teclado;
    private int[][] mat;
    
    public void cargar() {
        teclado=new Scanner(System.in);
        System.out.print("Cuantas fila tiene la matriz:");
        int filas=teclado.nextInt();
        System.out.print("Cuantas columnas tiene la matriz:");
        int columnas=teclado.nextInt();
        mat=new int[filas][columnas];
        for(int f=0;f<mat.length;f++) {
            for(int c=0;c<mat[f].length;c++) {
                System.out.print("Ingrese componente:");
                mat[f][c]=teclado.nextInt();
            }
        }
    }
    
    public void imprimir() {
        for(int f=0;f<mat.length;f++) {
            for(int c=0;c<mat[f].length;c++) {
                System.out.print(mat[f][c]+" ");
            }
            System.out.println();
        }
    }
    
    public void imprimirUltimaFila() {
     System.out.println("Ultima fila");
        for(int c=0;c<mat[mat.length-1].length;c++) {
             System.out.print(mat[mat.length-1][c]+" ");
        }
    }
    
    public static void main(String[] ar) {
        Matriz5 ma=new Matriz5();
        ma.cargar();
        ma.imprimir();
        ma.imprimirUltimaFila();
    }   
}

En este ejemplo cada vez que se ejecute el programa el tamaño de la matriz lo define el usuario, para ello ingresamos por teclado dos enteros y seguidamente procedemos a crear la matriz con dichos valores:
System.out.print("Cuantas fila tiene la matriz:");
        int filas=teclado.nextInt();
        System.out.print("Cuantas columnas tiene la matriz:");
        int columnas=teclado.nextInt();
        mat=new int[filas][columnas];

Ahora las estructuras repetitivas las acotamos preguntando a la misma matriz la cantidad de filas y la cantidad de elementos de cada fila(mat.length almacena la cantidad de filas de la matriz y mat[f].length cuando f vale cero accedemos a la cantidad de elementos de la fila cero y así sucesivamente para cada valor de f):
for(int f=0;f<mat.length;f++) {
            for(int c=0;c<mat[f].length;c++) {
                System.out.print("Ingrese componente:");
                mat[f][c]=teclado.nextInt();
            }
        }

El algoritmo de impresión es idéntico al visto anteriormente con la modificación de las condiciones de los for:
public void imprimir() {
        for(int f=0;f<mat.length;f++) {
            for(int c=0;c<mat[f].length;c++) {
                System.out.print(mat[f][c]+" ");
            }
            System.out.println();
        }
    }

Para imprimir la última fila debemos disponer un valor fijo en el subíndice de la fila (en este caso no podemos disponer un número fijo sino preguntarle a la misma matriz la cantidad de filas y restarle uno ya que las filas comienzan a numerarse a partir de cero: mat[mat.length-1][c])

También la condición del for debemos acceder al atributo length de la última fila mat[mat.length-1].length
for(int c=0;c<mat[mat.length-1].length;c++) {
             System.out.print(mat[mat.length-1][c]+" ");
        }

Problema 2:

Crear una matriz de n * m filas (cargar n y m por teclado) Imprimir el mayor elemento y la fila y columna donde se almacena.

Programa:

import java.util.Scanner;
public class Matriz6 {
    private Scanner teclado;
    private int[][] mat;
    
    public void cargar() {
        teclado=new Scanner(System.in);
        System.out.print("Cuantas fila tiene la matriz:");
        int filas=teclado.nextInt();
        System.out.print("Cuantas columnas tiene la matriz:");
        int columnas=teclado.nextInt();
        mat=new int[filas][columnas];
        for(int f=0;f<mat.length;f++) {
            for(int c=0;c<mat[f].length;c++) {
                System.out.print("Ingrese componente:");
                mat[f][c]=teclado.nextInt();
            }
        }
    }
        
    public void imprimirMayor() {
     int mayor=mat[0][0];
     int filamay=0;
     int columnamay=0;
        for(int f=0;f<mat.length;f++) {
            for(int c=0;c<mat[f].length;c++) {
                if (mat[f][c]>mayor) {
                    mayor=mat[f][c];
                    filamay=f;
                    columnamay=c;
                }
            }
        }
        System.out.println("El elemento mayor es:"+mayor);
        System.out.println("Se encuentra en la fila:"+filamay+ " y en la columna: "+columnamay);
    }
    
    public static void main(String[] ar) {
        Matriz6 ma=new Matriz6();
        ma.cargar();
        ma.imprimirMayor();
    }   
}

Para obtener el mayor elemento de la matriz y la fila y columna donde se ubica debemos inicializar una variable mayor con el elemento de la fila cero y columna cero (esto lo hacemos suponiendo que en dicha posición se almacena el mayor):
int mayor=mat[0][0];
     int filamay=0;
     int columnamay=0;

Luego mediante dos for recorremos todos los elementos de la matriz y cada vez que encontramos un elemento mayor al actual procedemos a actualizar la variable mayor y la posición donde se almacena:
for(int f=0;f<mat.length;f++) {
            for(int c=0;c<mat[f].length;c++) {
                if (mat[f][c]>mayor) {
                    mayor=mat[f][c];
                    filamay=f;
                    columnamay=c;
                }
            }
        }

Problemas propuestos

  1. Crear una matriz de n * m filas (cargar n y m por teclado) Intercambiar la primer fila con la segundo. Imprimir luego la matriz.
  2. Crear una matriz de n * m filas (cargar n y m por teclado) Imprimir los cuatro valores que se encuentran en los vértices de la misma (mat[0][0] etc.)

14-7 Estructura de datos tipo matriz

Una matriz es una estructura de datos que permite almacenar un CONJUNTO de datos del MISMO tipo.
Con un único nombre se define la matriz y por medio de DOS subíndices hacemos referencia a cada elemento de la misma (componente)

matriz

Hemos graficado una matriz de 3 filas y 5 columnas. Para hacer referencia a cada elemento debemos indicar primero la fila y luego la columna, por ejemplo en la componente 1,4 se almacena el valor 97.
En este ejemplo almacenamos valores enteros. Todos los elementos de la matriz deben ser del mismo tipo (int, float, String etc.)

Las filas y columnas comienzan a numerarse a partir de cero, similar a los vectores.
Una matriz se la puede representar por un conjunto de vectores.

Problema 1:

Crear una matriz de 3 filas por 5 columnas con elementos de tipo int, cargar sus componentes y luego imprimirlas.

Programa:

import java.util.Scanner;
public class Matriz1 {
    private Scanner teclado;
    private int[][] mat;
    
    public void cargar() {
        teclado=new Scanner(System.in);
        mat=new int[3][5];
        for(int f=0;f<3;f++) {
            for(int c=0;c<5;c++) {
                System.out.print("Ingrese componente:");
                mat[f][c]=teclado.nextInt();
            }
        }
    }
    
    public void imprimir() {
        for(int f=0;f<3;f++) {
            for(int c=0;c<5;c++) {
                System.out.print(mat[f][c]+" ");
            }
            System.out.println();
        }
    }
    
    public static void main(String[] ar) {
        Matriz1 ma=new Matriz1();
        ma.cargar();
        ma.imprimir();
    }   
}

Para definir una matriz debemos antecederle los corchetes abiertos y cerrados dos veces:
private int[][] mat;

De esta forma el compilador de Java puede diferenciar los vectores de las matrices.

Para crear la matriz, es decir hacer la reserva de espacio de todas sus componentes debemos utilizar el operador new y mediante dos subíndices indicamos la cantidad de filas y columnas que tendrá la matriz:
mat=new int[3][5];

Luego debemos pasar a cargar sus 15 componentes (cada fila almacena 5 componentes y tenemos 3 filas)
Lo más cómodo es utilizar un for anidado, el primer for que incrementa el contador f lo utilizamos para recorrer las filas y el contador interno llamado c lo utilizamos para recorrer las columnas.
Cada vez que se repite en forma completa el for interno se carga una fila completa, primero se carga la fila cero en forma completa, luego la fila uno y finalmente la fila 2.
Siempre que accedemos a una posición de la matriz debemos disponer dos subíndices que hagan referencia a la fila y columna mat[f][c]):
for(int f=0;f<3;f++) {
            for(int c=0;c<5;c++) {
                System.out.print("Ingrese componente:");
                mat[f][c]=teclado.nextInt();
            }
        }

Para imprimir la matriz de forma similar utilizamos dos for para acceder a cada elemento de la matriz:
for(int f=0;f<3;f++) {
            for(int c=0;c<5;c++) {
                System.out.print(mat[f][c]+" ");
            }
            System.out.println();
        }
    }

Cada vez que se ejecuta todas las vueltas del for interno tenemos en pantalla una fila completa de la matriz, por eso pasamos a ejecutar un salto de línea (con esto logramos que en pantalla los datos aparezcan en forma matricial):
System.out.println();

Problema 2:

Crear y cargar una matriz de 4 filas por 4 columnas. Imprimir la diagonal principal.

x    -    -    -
-    x    -    -
-    -    x    -
-    -    -    x

Programa:

import java.util.Scanner;
public class Matriz2 {
    private Scanner teclado;
    private int[][] mat;
    
    public void cargar() {
        teclado=new Scanner(System.in);
        mat=new int[4][4];
        for(int f=0;f<4;f++) {
            for(int c=0;c<4;c++) {
                System.out.print("Ingrese componente:");
                mat[f][c]=teclado.nextInt();
            }
        }
    }
    
    public void imprimirDiagonalPrincipal() {
        for(int k=0;k<4;k++) {
            System.out.print(mat[k][k]+" ");
        }
    }
    
    public static void main(String[] ar) {
        Matriz2 ma=new Matriz2();
        ma.cargar();
        ma.imprimirDiagonalPrincipal();
    }   
}

La definición, creación y carga de la matriz no varían con el ejemplo anterior.
Para imprimir la diagonal principal de la matriz lo más conveniente es utilizar un for que se repita 4 veces y disponer como subíndice dicho contador (los elementos de la diagonal principal coinciden los valores de la fila y columna):
for(int k=0;k<4;k++) {
            System.out.print(mat[k][k]+" ");
        }

Problema 3:

Crear y cargar una matriz de 3 filas por 4 columnas. Imprimir la primer fila. Imprimir la última fila e imprimir la primer columna.

Programa:

import java.util.Scanner;
public class Matriz3 {
    private Scanner teclado;
    private int[][] mat;
    
    public void cargar() {
        teclado=new Scanner(System.in);
        mat=new int[3][4];
        for(int f=0;f<3;f++) {
            for(int c=0;c<4;c++) {
                System.out.print("Ingrese componente:");
                mat[f][c]=teclado.nextInt();
            }
        }
    }
    
    public void primerFila() {
     System.out.println("Primer fila de la matriz:");
        for(int c=0;c<4;c++) {
            System.out.println(mat[0][c]);
        }
    }
    
    public void ultimaFila() {
     System.out.println("Ultima fila de la matriz:");
        for(int c=0;c<4;c++) {
            System.out.println(mat[2][c]);
        }
    }
    
    public void primerColumna() {
     System.out.println("Primer columna:");
        for(int f=0;f<3;f++) {
            System.out.println(mat[f][0]);
        }
    }
    
    public static void main(String[] ar) {
        Matriz3 ma=new Matriz3();
        ma.cargar();
        ma.primerFila();
        ma.ultimaFila();
        ma.primerColumna();
    }   
}
Creamos una matriz de 3 filas y 4 columnas:
mat=new int[3][4];

Luego de cargarla el primer método que codificamos es el que imprimime la primer fila. Disponemos un for para recorrer las columnas, ya que la fila siempre será la cero. Como son cuatro los elementos de la primer fila el for se repite esta cantidad de veces:
System.out.println("Primer fila de la matriz:");
        for(int c=0;c<4;c++) {
            System.out.println(mat[0][c]);
        }

Para imprimir la última fila el algoritmo es similar, disponemos un for que se repita 4 veces y en el subíndice de la fila disponemos el valor 2 (ya que la matriz tiene 3 filas):
System.out.println("Ultima fila de la matriz:");
        for(int c=0;c<4;c++) {
            System.out.println(mat[2][c]);
        }

Para imprimir la primer columna el for debe repetirse 3 veces ya que la matriz tiene 3 filas. Dejamos constante el subíndice de la columna con el valor cero:
System.out.println("Primer columna:");
        for(int f=0;f<3;f++) {
            System.out.println(mat[f][0]);
        }

Problemas propuestos

  1. Crear una matriz de 2 filas y 5 columnas. Realizar la carga de componentes por columna (es decir primero ingresar toda la primer columna, luego la segunda columna y así sucesivamente)
    Imprimir luego la matriz.

14-6 Vectores (ordenamiento con vectores paralelos)

Cuando se tienen vectores paralelos y se ordena uno de ellos hay que tener la precaución de intercambiar los elementos de los vectores paralelos.

Problema 1:

Confeccionar un programa que permita cargar los nombres de 5 alumnos y sus notas respectivas. Luego ordenar las notas de mayor a menor. Imprimir las notas y los nombres de los alumnos.

 

Programa:

import java.util.Scanner;
public class PruebaVector16 {
    private Scanner teclado;
    private String[] nombres;
    private int[] notas;
    
    public void cargar() {
        teclado=new Scanner(System.in);
        nombres=new String[5];
        notas=new int[5];
        System.out.println("Carga de nombres y notas");
        for(int f=0;f<nombres.length;f++) {
            System.out.print("Ingese el nombre del alumno:");
            nombres[f]=teclado.next();
            System.out.print("Ingrese la nota del alumno:");
            notas[f]=teclado.nextInt();
        }
    }        
    
    public void ordenar() {
        for(int k=0;k<notas.length;k++) {
            for(int f=0;f<notas.length-1-k;f++) {
                if (notas[f]<notas[f+1]) {
                    int auxnota;
                    auxnota=notas[f];
                    notas[f]=notas[f+1];
                    notas[f+1]=auxnota;
                    String auxnombre;
                    auxnombre=nombres[f];
                    nombres[f]=nombres[f+1];
                    nombres[f+1]=auxnombre;
                }
            }
        }
    }
        
    public void imprimir() {
    System.out.println("Nombres de alumnos y notas de mayor a menor");
        for(int f=0;f<notas.length;f++) {
            System.out.println(nombres[f] + " - " + notas[f]);
        }
    }        

    public static void main(String[] ar) {
        PruebaVector16 pv=new PruebaVector16();
        pv.cargar();
        pv.ordenar();
        pv.imprimir();
    }   
}

Definimos los dos vectores:
private String[] nombres;
    private int[] notas;

Creamos los dos vectores paralelos con cinco elementos cada uno:
nombres=new String[5];
        notas=new int[5];

En el proceso de ordenamiento dentro de los dos for verificamos si debemos intercambiar los elementos del vector notas:
for(int k=0;k<notas.length;k++) {
            for(int f=0;f<notas.length-1-k;f++) {
                if (notas[f]<notas[f+1]) {

En el caso que la nota de la posición 'f' sea menor a de la posición siguiente 'f+1' procedemos a intercambiar las notas:

int auxnota;
                    auxnota=notas[f];
                    notas[f]=notas[f+1];
                    notas[f+1]=auxnota;

y simultánemamente procedemos a intercambiar los elementos del vector paralelo (con esto logramos que los dos vectores continuen siendo vectores paralelos):

String auxnombre;
                    auxnombre=nombres[f];
                    nombres[f]=nombres[f+1];
                    nombres[f+1]=auxnombre;

Como vemos utilizamos dos auxiliares distintos porque los elementos de los dos vectores son de distinto tipo (int y String)

Si deseamos ordenar alfabéticamente la condición dependerá del vector nombres.

Problemas propuestos

  1. Cargar en un vector los nombres de 5 paises y en otro vector paralelo la cantidad de habitantes del mismo. Ordenar alfabéticamente e imprimir los resultados. Por último ordenar con respecto a la cantidad de habitantes (de mayor a menor) e imprimir nuevamente.

martes, 1 de marzo de 2011

14-5 Vectores (ordenamiento)

El ordenamiento de un vector se logra intercambiando las componentes de manera que:

vec[0] <= vec[1] <= vec[2] etc.

El contenido de la componente vec[0] sea menor o igual al contenido de la componente vec[1] y así sucesivamente.

Si se cumple lo dicho anteriormente decimos que el vector está ordenado de menor a mayor. Igualmente podemos ordenar un vector de mayor a menor.

Se puede ordenar tanto vectores con componentes de tipo int, float como String. En este último caso el ordenamiento es alfabético.

Problema 1:

Se debe crear un vector donde almacenar 5 sueldos. Ordenar el vector sueldos de menor a mayor.


ordenamiento de un vector

Esta primera aproximación tiene por objetivo analizar los intercambios de elementos dentro del vector.

El algoritmo consiste en comparar si la primera componente es mayor a la segunda, en caso que la condición sea verdadera, intercambiamos los contenidos de las componentes.

Vamos a suponer que se ingresan los siguientes valores por teclado:

1200
750
820
550
490
 
En este ejemplo: ¿es 1200 mayor a 750? La respuesta es verdadera, por lo tanto intercambiamos el contenido de la componente 0 con el de la componente 1.

Luego comparamos el contenido de la componente 1 con el de la componente 2: ¿Es 1200 mayor a 820?
La respuesta es verdadera entonces intercambiamos.

Si hay 5 componentes hay que hacer 4 comparaciones, por eso el for se repite 4 veces.

Generalizando: si el vector tiene N componentes hay que hacer N-1 comparaciones.


Cuando  f = 0  f = 1  f  = 2  f = 3
  
  750  750  750  750
  1200  820  820  820
  820  1200  550  550
  550  550  1200  490
  490  490  490  1200

Podemos ver cómo el valor más grande del vector desciende a la última componente. Empleamos una variable auxiliar (aux) para el proceso de intercambio:

aux=sueldos[f];
sueldos[f]=sueldos[f+1];
sueldos[f+1]=aux;

Al salir del for en este ejemplo el contenido del vector es el siguiente:

750
820
550
490
1200

Analizando el algoritmo podemos comprobar que el elemento mayor del vector se ubica ahora en el último lugar.

Podemos definir otros vectores con distintos valores y comprobar que siempre el elemento mayor queda al final.

Pero todavía con este algoritmo no se ordena un vector. Solamente está ordenado el último elemento del vector.

Ahora bien, con los 4 elementos que nos quedan podemos hacer el mismo proceso visto anteriormente, con lo cual quedará ordenado otro elemento del vector. Este proceso lo repetiremos hasta que quede ordenado por completo el vector.

Como debemos repetir el mismo algoritmo podemos englobar todo el bloque en otra estructura repetitiva.


ordenamiento de un vector


Realicemos una prueba del siguiente algoritmo:

Cuando k = 0
  f = 0  f = 1  f = 2  f = 3
  750  750  750  750
  1200  820  820  820
  820  1200  550  550
  550  550  1200  490
  490  490  490  1200
  
Cuando k = 1
  f = 0  f = 1  f  = 2  f = 3
  750  750  750  750 
  820  550  550  550
  550  820  490  490
  490  490  820  820
  1200  1200  1200  1200

Cuando k = 2
  f = 0  f = 1  f  = 2  f = 3
  550  550  550  550
  750  490  490  490
  490  750  750  750
  820  820  820  820
  1200  1200  1200  1200


Cuando k = 3
  f = 0  f = 1  f  = 2  f = 3
  490  490  490  490
  550  550  550  550
  750  750  750  750
  820  820  820  820
  1200  1200  1200  1200

¿Porque repetimos 4 veces el for externo?

Como sabemos cada vez que se repite en forma completa el for interno queda ordenada una componente del vector. A primera vista diríamos que deberíamos repetir el for externo la cantidad de componentes del vector, en este ejemplo el vector sueldos tiene 5 componentes.

Si observamos, cuando quedan dos elementos por ordenar, al ordenar uno de ellos queda el otro automáticamente ordenado (podemos imaginar que si tenemos un vector con 2 elementos no se requiere el for externo, porque este debería repetirse una única vez)
Una última consideración a este ALGORITMO de ordenamiento es que los elementos que se van ordenando continuamos comparándolos.

Ejemplo: En la primera ejecución del for interno el valor 1200 queda ubicado en la posición 4 del vector. En la segunda ejecución comparamos si el 820 es mayor a 1200, lo cual seguramente será falso.

Podemos concluir que la primera vez debemos hacer para este ejemplo 4 comparaciones, en la segunda ejecución del for interno debemos hacer 3 comparaciones y en general debemos ir reduciendo en uno la cantidad de comparaciones.

Si bien el algoritmo planteado funciona, un algoritmo más eficiente, que se deriva del anterior es el plantear un for interno con la siguiente estructura: (f=0 ; f<4-k; f++)
Es decir restarle el valor del contador del for externo.

Programa:

import java.util.Scanner;
public class PruebaVector13 {
    private Scanner teclado;
    private int[] sueldos;

    public void cargar() {
        teclado=new Scanner(System.in);
        sueldos=new int[5];
        for(int f=0;f<sueldos.length;f++) {
            System.out.print("Ingrese el sueldo:");
            sueldos[f]=teclado.nextInt();
        }
    }
 
    public void ordenar() {
        for(int k=0;k<4;k++) {
            for(int f=0;f<4-k;f++) {
                if (sueldos[f]>sueldos[f+1]) {
                    int aux;
                    aux=sueldos[f];
                    sueldos[f]=sueldos[f+1];
                    sueldos[f+1]=aux;
                }
            }
        }
    }
 
    public void imprimir() {
        System.out.println("Sueldos ordenados de menor a mayor.");
        for(int f=0;f<sueldos.length;f++) {
            System.out.println(sueldos[f]);
        }
    }
 
    public static void main(String[] ar) {
        PruebaVector13 pv=new PruebaVector13();
        pv.cargar();
        pv.ordenar();
        pv.imprimir();
    }
}

También podemos ordenar vectores cuyas componentes sean de tipo String. Para esto no podemos utilizar el operador > sino debemos utilizar un método de la clase String:

String cad1="juan";
String cad2="analia";
if (cad1.compareTo(cad2)>0)
{
  System.out.println(cad1 + " es mayor alfabéticamente que " + cad2);
}
 
El método compareTo retorna un valor mayor a cero si cad1 es mayor alfabéticamente. En este ejemplo cad1 tiene un valor alfabéticamente mayor a cad2, luego el compareTo retorna un valor mayor a cero.
Si los dos String son exactamente iguales el método compareTo retorna un cero, y finalmente si cad1 es menor alfabeticamente retorna un valor menor a cero.

Problema 2:

Definir un vector donde almacenar los nombres de 5 paises. Confeccionar el algoritmo de ordenamiento alfabético.

Programa:

import java.util.Scanner;
public class PruebaVector14 {
    private Scanner teclado;
    private String[] paises;
 
    public void cargar() {
        teclado=new Scanner(System.in);
        paises=new String[5];
        for(int f=0;f<paises.length;f++) {
            System.out.print("Ingrese el nombre del pais:");
            paises[f]=teclado.next();
        }
    }

    public void ordenar() {
        for(int k=0;k<4;k++) {
            for(int f=0;f<4-k;f++) {
                if (paises[f].compareTo(paises[f+1])>0) {
                    String aux;
                    aux=paises[f];
                    paises[f]=paises[f+1];
                    paises[f+1]=aux;
                }
            }
        }
    }
 
    public void imprimir() {
     System.out.println("Paises ordenados en forma alfabética:");
        for(int f=0;f<paises.length;f++) {
            System.out.println(paises[f]);
        }
    }

    public static void main(String[] ar) {
        PruebaVector14 pv=new PruebaVector14();
        pv.cargar();
        pv.ordenar();
        pv.imprimir();
    }
}
Definimos un vector de tipo String:

private String[] paises;

Lo creamos indicando que almacenará cinco elementos:

paises=new String[5];

Procedemos a cargar el vector:

for(int f=0;f<paises.length;f++) {
            System.out.print("Ingrese el nombre del pais:");
            paises[f]=teclado.next();
        }

Para el ordenamiento utilizamos el método compareTo para verificar si tenemos que intercambiar las componentes:

if (paises[f].compareTo(paises[f+1])>0) {

En el caso que si tenemos que intercambiarla utilizamos un auxilir de tipo String:

String aux;
                    aux=paises[f];
                    paises[f]=paises[f+1];
                    paises[f+1]=aux;

Problemas propuestos

  1. Cargar un vector de n elementos de tipo entero. Ordenar posteriormente el vector.