viernes, 27 de noviembre de 2020

Conectar SQLite con Eclipse

Programas o Software requerido

Para realizar la conexión necesitamos tener los siguientes programas:
  • Eclipse (Pueden elegir la versión que deseen así como la arquitectura de su Pc o Mac): http://www.eclipse.org/downloads/packages
  • El driver JDBC de SQLite (sqlite-jdbc-3.30.1).
  • Un programa que administre bases de datos de SQLite para crear las bases de datos y opcionalmente comprobar si los cambios realizados en el programa JAVA realizan cambios en la base de datos.

Paso 1 - La base de datos

Si ya posee la base de datos, solo basta conocer la dirección exacta de esta. Si no posee la base de datos, puede seguir el siguiente tutorial para generar una: https://inlearningcode.blogspot.com/2020/11/sqlite-tabla.html

Paso 2 - El proyecto en Eclipse

Ahora procedemos a Eclipse donde creamos un nuevo proyecto, colocamos el nombre del proyecto como queramos llamarlo. Luego continuamos y vamos a la pestaña Libraries (Bibliotecas) y dentro de ella agregamos una nueva (Add Library).

Despliega una nueva ventana y elegimos la opción Add External JARs y luego seleccionar el archivo JAR correspondiente, en mi caso el sqlite-jdbc-3.30.1.jar, y aceptar.

Dentro del proyecto se observa las bibliotecas del Jdk y el driver de conexión.

package util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Conectabd {
	private final String URL = "jdbc:sqlite:D:\\bd\\blog.db";
    private final String DRIVER = "org.sqlite.JDBC";

    
    public Connection conexionDB() throws SQLException{
    Connection c = null;
        try {
            Class.forName(DRIVER).newInstance();
            c = DriverManager.getConnection(URL);
        } catch (ClassNotFoundException | 
                 IllegalAccessException | 
                 InstantiationException | 
                 SQLException e) {
            throw new SQLException(e.getMessage());
        }
    
    return c;
    }
    		
	}
	
}

La constante URL es una combinación del JDBC y la ubicación real de la base de datos SQLite que es un archivo en sí. Mientras el DRIVER es para este caso "org.sqlite.JDBC"

Al ser una base de datos de SQLite un archivo, no requiere de usuario ni de contraseña, pero mantiene la misma lógica para llevar a cabo la conexión.

Paso 3 - Probando la clase de conexión

Creamos la siguiente clase Test.java

package test;

import java.sql.Connection;

import util.Conectabd;

public class Test {

	public static void main(String[] args) {

		Conectabd conectabd = new Conectabd();
		try (Connection c = conectabd.getConexion()) {
			System.out.print("Conexión exitosa");
		} catch (Exception e) {
			System.err.print("Error: "+e.getMessage());
		}
	}

}

Al ser ejecutada la clase devolverá: "Conexión exitosa" o indicará si ocurrió una excepción. Generalmente suelen ser un error en la redacción de la URL o el driver.

miércoles, 25 de noviembre de 2020

Métodos de búsqueda

Búsqueda secuencial o lineal

Consiste en recorrer una estructura de datos comparando cada elemento con el valor buscado, si el elemento buscado se encuentra al inicio, el tiempo de búsqueda será muy corto, pero será cada vez más largo mientras el elemento se encuentre más cerca del final o no se encuentre.

Algoritmo de implementación

package busqueda;

public class Busca {

    public static Integer Secuencial(Integer[] data, int valor) {
        Integer pos = null;
        for (int i = 0; i < data.length; i++) {
            if (valor == data[i]) {
                pos = i;
                break;
            }
        }
        return pos;
    }
}

Aplicando el algoritmo a un Array

package test;

import busqueda.Busca;

public class TestBusqueda {

    public static void main(String[] args) {
        Integer[] datos = {2, 255, 10, 0, 11, 1172, 1};
        System.out.println("Array: " + Arrays.toString(datos));
        
        //Búsqueda de la posición de forma secuencial		
        Integer index = Busca.Secuencial(datos, 11); // Busca 11
        System.out.println("Buscando 11 ...");
        //Mostrar resultado
        if (index != null) {
            System.out.println("Elemento encontrado en la posición " + index);
        } else {
            System.out.println("Elemento no encontrado");
        }
		
        index = Busca.Secuencial(datos, 12); // Busca 12
        System.out.println("Buscando 12 ...");
        //Mostrar resultado
        if (index != null) {
            System.out.println("Elemento encontrado en la posición " + index);
        } else {
            System.out.println("Elemento no encontrado");
        }
    }
}

El resultado sería el siguiente:

Array: [2, 255, 10, 0, 11, 1172, 1]

Buscando 11 ...
Elemento encontrado en la posición 4

Buscando 12 ...
Elemento no encontrado


Búsqueda binaria

Consiste en recorrer una estructura de datos dividiéndola constantemente en dos partes hasta encontrar la coincidencia de búsqueda. Este método requiere que la estructura de datos este previamente ordenada de forma ascendente o descedente.

Algoritmo de implementación

package busqueda;

public class Busca {

    public static Integer Binario(Integer[] data, Integer valor) {
        int li = 0;
        int ls = data.length;
        while (li <= ls) {
            int lm = (ls - li) / 2 + li;
            if (data[lm] < valor) {
                li = lm + 1;
            } else if (data[lm] > valor) {
                ls = lm - 1;
            } else {
                return lm;
            }
        }
        return null;
    }
}

Aplicando el algoritmo a un Array

package test;

import busqueda.Busca;
import java.util.Arrays;

public class TestBusqueda {

    public static void main(String[] args) {
        Integer[] datos = {2, 255, 10, 0, 11, 1172, 1};
        System.out.println("Array: " + Arrays.toString(datos));
        
        //Búsqueda de la posición por búsqueda binaria
        Arrays.sort(datos); // Ordenamiento de datos
        System.out.println("Array ordenado: " + Arrays.toString(datos));
        
        Integer index = Busca.Binario(datos, 172); 
        System.out.println("Buscando 172 ..."); 
        //Mostrar resultado
        if (index != null) {
            System.out.println("Elemento encontrado en la posición " + index);
        } else {
            System.out.println("Elemento no encontrado");
        }
        
        index = Busca.Binario(datos, 255);
        System.out.println("Buscando 255 ...");
        //Mostrar resultado
        if (index != null) {
            System.out.println("Elemento encontrado en la posición " + index);
        } else {
            System.out.println("Elemento no encontrado");
        }
    }
}

El resultado sería el siguiente:

Array: [2, 255, 10, 0, 11, 1172, 1]
Array ordenado: [0, 1, 2, 10, 11, 255, 1172]

Buscando 172 ...
Elemento no encontrado

Buscando 255 ...
Elemento encontrado en la posición 5

miércoles, 18 de noviembre de 2020

Métodos de ordenamiento

Los problemas más comunes en la informática son la búsqueda y el ordenamiento. El proceso de ordenar consiste en recolocar los elementos de un array o colección ya sea de mayor a menor o viceversa con el fin de acelerar la búsqueda de la información.

En este aspecto existe una multitud de algoritmos de ordenamiento clasificados de diversas formas como la estabilidad, su complejidad, ubicación del proceso al ordenar, etc.

Entre los múltiples algoritmos tenemos:

  • Ordenamiento por burbuja
  • Ordenamiento por montículos
  • Ordenamiento por selección
  • Ordenamiento por inserción
  • Ordenamiento rápido (QuickSort)
  • Ordenamiento shell

Ordenamiento por burbuja

La clase con el siguiente código permite ordenar los elementos de un array unidimensional mediante este método.

package ordenamiento;

public class Ordena {
    
    //Ordenamiento de burbuja
    public static void burbuja(Integer[] data) {
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data.length - 1; j++) {
                if (data[j] > data[j + 1]) {
                    Integer temp = data[j];
                    data[j] = data[j + 1];
                    data[j + 1] = temp;
                }
            }
        }
    }
}

Para comprobar el funcionamiento se utiliza lo siguiente:

package test;

import ordenamiento.Ordena;

public class TestOrdenar {

    public static void main(String[] args) {
        Integer[] vals = {15, 60, 8, 16, 44, 27, 12, 35};
        Ordena.burbuja(vals);
        for (Integer val : vals) {
            System.out.println(val);
        }

    }
}

La salida del resultado sería:

8
12
15
16
27
35
44
60

Se comprueba el funcionamiento de este algoritmo.


Ordenamiento por selección

La clase con el siguiente código permite ordenar los elementos de un array unidimensional mediante este método.

package ordenamiento;

public class Ordena {
    
    //Ordenamiento por selección
    public static void seleccion(Integer[] data) {
        for (int i = 0; i < data.length; i++) {
            for (int j = i; j < data.length; j++) {
                if (data[i] > data[j]) {
                    Integer aux = data[j];
                    data[j] = data[i];
                    data[i] = aux;
                }
            }
        }
    }
}

Para comprobar el funcionamiento se utiliza lo siguiente:

package test;

import ordenamiento.Ordena;

public class TestOrdenar {

    public static void main(String[] args) {
        Integer[] vals = {15, 60, 8, 16, 44, 27, 12, 35};
        Ordena.seleccion(vals);
        for (Integer val : vals) {
            System.out.println(val);
        }

    }
}

La salida del resultado sería:

8
12
15
16
27
35
44
60

Se comprueba el funcionamiento de este algoritmo.


Ordenamiento por inserción

La clase con el siguiente código permite ordenar los elementos de un array unidimensional mediante este método.

package ordenamiento;

public class Ordena {
    
    //Ordenamiento por inserción
    public static void insercion(Integer[] data) {
        for (int i = 1; i < data.length; i++) {
            Integer aux = data[i];
            int j = i - 1;
            while (j >= 0 && data[j] > aux) {
                data[j + 1] = data[j];
                j--;
            }
            data[j + 1] = aux;
        }
    }
}

Para comprobar el funcionamiento se utiliza lo siguiente:

package test;

import ordenamiento.Ordena;

public class TestOrdenar {

    public static void main(String[] args) {
        Integer[] vals = {15, 60, 8, 16, 44, 27, 12, 35};
        Ordena.insercion(vals);        
        for (Integer val : vals) {
            System.out.println(val);
        }

    }
}

La salida del resultado sería:

8
12
15
16
27
35
44
60

Se comprueba el funcionamiento de este algoritmo.


Ordenamiento por montículos (HeapSort)

La clase con el siguiente código permite ordenar los elementos de un array unidimensional mediante este método.

package ordenamiento;

public class Ordena {
    
    //Ordenamiento por montículos
    public static void heapsort(Integer[] data) {
        data = monticulo(data, data.length);
        for (int i = 0; i < data.length; i++) {
            data = eliminarRaiz(data, data.length - i);
            data = monticulo(data, data.length - i - 1);
        }
    }
    
    //Función para construir montículo
    private static Integer[] monticulo(Integer[] data, int n) {
        for (int i = 0; i < n; i++) {
            if (padre(i) != -1) {
                int p = data[padre(i)];
                if (data[i] > p) {
                    data[padre(i)] = data[i];
                    data[i] = p;
                    monticulo(data, n);
                }
            }
        }
        return data;
    }        
    
    //Función para determinar padres
    private static int padre(int index) {
        return (index == 0) ? -1 : (index - 1) / 2;
    }

    //Función para eliminar las raices
    private static Integer[] eliminarRaiz(Integer[] data, int n) {
        Integer aux;
        aux = data[n - 1];
        data[n - 1] = data[0];
        data[0] = aux;
        return data;
    }
}

Para comprobar el funcionamiento se utiliza lo siguiente:

package test;

import ordenamiento.Ordena;

public class TestOrdenar {

    public static void main(String[] args) {
        Integer[] vals = {15, 60, 8, 16, 44, 27, 12, 35};
        Ordena.heapsort(vals);
        for (Integer val : vals) {
            System.out.println(val);
        }

    }
}

La salida del resultado sería:

8
12
15
16
27
35
44
60

Se comprueba el funcionamiento de este algoritmo.

lunes, 9 de noviembre de 2020

Pilas (Stacks)

 Desde el punto de vista teórico una pila es un tipo de dato abstracto (TDA) que sigue el principio LIFO (last in, first out) que implica que el último elemento en ser agregado en la pila es también el primero en ser removido de la misma.

En la imagen se observa una pila con tres elementos, cuando se inserta uno nuevo, este se coloca al final de la pila (elemento D).
Cuando se elimina un elemento, se remueve el último en haber ingresado, en caso de la pila es el elemento D.

En el mundo real podemos encontrar este ejemplo al apilar platos en un punto, cuando queremos mover los platos uno por uno se comienza retirando el último plato colocado.

Stacks en Java

Se puede crear una pila de forma sencilla con la clase Stack que hereda de la clase Vector.

El siguiente ejemplo ilustra como construir una pila, agregar elementos y luego irlos retirando. Para ello, se crea una colección llamada pila de tipo Stack que almacena valores enteros.

package test;

import java.util.Stack;

public class Pilas {

    public static void main(String[] args) {
        Stack<Integer> pila = new Stack<>();

        System.out.println("Agregando valores");
        for (int i = 0; i < 5; i++) {
            pila.push(i);
            System.out.println("Valor: " + i);
        }
        
        System.out.println("\nRetirando valores");
        while (!pila.isEmpty()) {
            System.out.println("Valor: " + pila.pop());            
        }
    }
}

La salida del resultado sería:

Agregando valores
Valor: 0
Valor: 1
Valor: 2
Valor: 3
Valor: 4

Retirando valores
Valor: 4
Valor: 3
Valor: 2
Valor: 1
Valor: 0

El último elemento en ser agregado es "4" y al retirar a los elementos, el primero en ser removido también es el "4" comprobando el principio LIFO.

Creando una clase Colas


La siguiente clase emula de forma simple el funcionamiento de una cola, para ello utiliza un array de tipo Object

package tda;

public class Pilas {

    private Object[] data;
    private final int length;
    private int pointer;

    public Pilas(int length) {
        this.length = length;
        this.data = new Object[length];
        this.pointer = -1;
    }

    public void add(Object element) {
        this.data[pointer+1] = element;
        pointer = (pointer < length - 1) ? pointer + 1 : pointer;
    }

    public Object[] getData() {
        return this.data;
    }

    public int getLength() {
        return length;
    }

    public Object pop() {
        Object value = this.data[pointer];
        this.data[pointer] = null;
        pointer--;
        return value;
    }
}

Para comprobar el funcionamiento se utiliza lo siguiente:

package test;

import java.util.Arrays;
import tda.Pilas;

public class TestPilas {

    public static void main(String[] args) {
        Pilas pilaInt = new Pilas(4);
        pilaInt.add(0);
        pilaInt.add(1);
        pilaInt.add(2);
        pilaInt.add(3);
        for (int i = 0; i < 4; i++) {
            System.out.println("Dato ingresado: "+pilaInt.getData()[i]);
        }
        System.out.println("=================================");
        System.out.println("Sale: "+pilaInt.pop());
        System.out.println("Sale: "+pilaInt.pop());
        System.out.println("Sale: "+pilaInt.pop());
        pilaInt.add(5);
        System.out.println("=================================");
        System.out.println(Arrays.toString(pilaInt.getData()));
    }
}

La salida del resultado sería:

Dato ingresado: 0
Dato ingresado: 1
Dato ingresado: 2
Dato ingresado: 3
=================================
Sale: 3
Sale: 2
Sale: 1
=================================
[0, 5, null, null]

Se comprueba el principio LIFO al insertar al final el 3, el primero en ser retirado es el mismo 3

Colas (Queues)

 Desde el punto de vista teórico una cola es un tipo de dato abstracto (TDA) que sigue el principio FIFO (first in, first out) que implica que el primer elemento en ser agregado en la cola es también el primero en ser removido de la misma.

En la imagen se observa una cola con tres elementos, cuando se inserta uno nuevo, este se coloca al final de la cola (elemento D).
Cuando se elimina un elemento, se remueve el primero en haber ingresado, en caso de la cola es el elemento A.

En el mundo real podemos encontrar este ejemplo en las colas de un banco, la cadena de impresión de documentos, etc.

En el caso de la cola en el banco, la primera persona en llegar es también la primera en irse (suponiendo una única ventanilla) y en los documentos a imprimir, la impresora imprime según el orden de llegada.

Queues en Java

Existen diversas colecciones que permite implementar de forma rápida y sencilla a las colas como la interfaz "Queue" o la clase "LinkedList"

El siguiente ejemplo ilustra como construir una cola, agregar elementos y luego irlos retirando. Para ello, se crea una colección llamada cola de tipo Queue con una implementación de lista enlazada (LinkedList) que almacena valores enteros.

package test;

import java.util.LinkedList;
import java.util.Queue;

public class Colas {

    public static void main(String[] args) {
        Queue<Integer> cola = new LinkedList<>();

        System.out.println("Agregando valores");
        for (int i = 0; i < 5; i++) {
            cola.add(i);
            System.out.println("Valor: " + i);
        }
        
        System.out.println("\nRetirando valores");
        while (cola.peek()!=null) {
            System.out.println("Valor: " + cola.poll());            
        }
    }
}

La salida del resultado sería:

Agregando valores
Valor: 0
Valor: 1
Valor: 2
Valor: 3
Valor: 4

Retirando valores
Valor: 0
Valor: 1
Valor: 2
Valor: 3
Valor: 4

El primer elemento en ser agregado es "0" y al retirar a los elementos, el primero en ser removido también es el "0" comprobando el principio FIFO.

Creando una clase Colas


La siguiente clase emula de forma simple el funcionamiento de una cola, para ello utiliza un array de tipo Object

package tda;

public class Colas {

    private Object[] data;
    private final int length;
    private int pointer;

    public Colas(int length) {
        this.length = length;
        this.data = new Object[length];
        this.pointer = -1;
    }

    public void add(Object element) {
        this.data[pointer+1] = element;
        pointer = (pointer < length - 1) ? pointer + 1 : pointer;
    }

    public Object[] getData() {
        return this.data;
    }

    public int getLength() {
        return length;
    }

    public Object pop() {
        Object value = this.data[0];
        for (int i = 0; i < data.length-1; i++) {
            data[i] = data[i+1];            
        }
        this.data[pointer] = null;
        pointer--;
        return value;
    }

}

Para comprobar el funcionamiento se utiliza lo siguiente:

package test;

import java.util.Arrays;
import tda.Colas;

public class TestColas {

    public static void main(String[] args) {
        Colas colaInt = new Colas(4);
        colaInt.add(0);
        colaInt.add(1);
        colaInt.add(2);
        colaInt.add(3);
        for (int i = 0; i < 4; i++) {
            System.out.println("Dato ingresado: "+colaInt.getData()[i]);
        }
        System.out.println("=================================");
        System.out.println("Sale: "+colaInt.pop());
        System.out.println("Sale: "+colaInt.pop());        
        System.out.println("Sale: "+colaInt.pop());
        System.out.println("=================================");
        colaInt.add(5); // Agregamos el 5
        System.out.println(Arrays.toString(colaInt.getData()));      
    }

}

La salida del resultado sería:

Dato ingresado: 0
Dato ingresado: 1
Dato ingresado: 2
Dato ingresado: 3
=================================
Sale: 0
Sale: 1
Sale: 2
=================================
[3, 5, null, null]

Se comprueba el principio FIFO al insertar primero al 0, el primero en ser retirado es el mismo 0