martes, 17 de noviembre de 2015

Tipo abstracto de datos Pila 

Una pila (stack) es una colección ordenada de elementos a los que sólo se puede acceder por un único lugar o extremo de la pila. Los elementos de la pila se añaden o quitan (borran) de la misma sólo por su parte superior (cima) de la pila. Las entradas de la pila deben ser eliminadas en el orden inverso al que se situaron en la misma. Por ejemplo, se puede crear una pila de libros, situando primero un diccionario, encima de él una enciclopedia y encima de ambos una novela de modo que la pila tendrá la novela en la parte superior.


Operaciones básicas de una pila.

Debido a su propiedad específica “último en entrar, primero en salir” se conoce a las pilas como estructura de datos LIFO (last-in/first-out). La pila se puede implementar guardando los elementos en un arreglo en cuyo caso su dimensión o longitud es fija. También se puede utilizar un Vector para almacenar los elementos. Otra forma de implementación consiste en construir una lista enlazada, cada elemento de la pila forma un nodo de la lista; la lista crece o decrece según se añaden o se extraen, respectivamente, elementos de la pila; ésta es una representación dinámica y no existe limitación en su tamaño excepto la memoria de la computadora. 
Una pila puede estar vacía (no tiene elementos) o llena (en la representación con un arreglo, si se ha llegado al último elemento). Si un programa intenta sacar un elemento de una pila vacía, se producirá un error, una excepción, debido a que esa operación es imposible; esta situación se denomina desbordamiento negativo (underflow). Por el contrario, si un programa intenta poner un elemento en una pila llena se produce un error, o excepción, de desbordamiento (overflow) o rebosamiento. 

Especificaciones de la pila.

Las operaciones que sirven para definir una pila y poder manipular su contenido son las siguientes. Tipo de dato           Elemento que se almacena en la pila
Operaciones
CrearPila                Inicia 
Insertar (push)        Pone un dato en la pila
Quitar (pop)           Retira (saca) un dato de la pila
Pila vacía               Comprueba si la pila no tiene elementos
Pila llena                Comprueba si la pila está llena de elementos
Limpiar pila           Quita todos sus elementos y deja la pila vacía
CimaPila                Obtiene el elemento cima de la pila

Tamaño de la pila   Número de elementos máximo que puede contener la pila.
Ejemplo 36.2 muestra cómo declarar una pila con un arreglo lineal. El tipo de los elementos de la pila es Object, lo que permite que pueda contener cualquier tipo de objeto.



  • Pila dinámica implementada con el vector.


La clase Vector es un contenedor de objetos que puede ser manejado para que crezca y decrezca dinámicamente. Los elementos de Vector son de tipo Object. Dispone de métodos para asignar un elemento en una posición (insertElementAt), para añadir un elemento a continuación del último (addElement), para obtener el elemento que se encuentra en una posición determinada (elementAt), para eliminar un elemento (removeElementAt) ...
La posición del último elemento añadido a la pila se mantiene con la variable cima. Inicialmente cima == −1, que es la condición de pila vacía. 
Insertar un nuevo elemento supone aumentar cima y asignar el elemento a la posición cima del Vector. La operación se realiza llamando al método addElement. No resulta necesario implementar el método pilaLlena ya que la capacidad del Vector crece dinámicamente. 
El método quitar( ) devuelve el elemento cima de la pila y lo elimina. Al utilizar un Vector, llamando a removeElementAt(cima) se elimina el elemento cima; a continuación se decrementa cima.
 La implementación es:
































  • Pila implementada con una lista enlazada.



Guardar los elementos de la pila en una lista enlazada permite que la pila crezca o decrezca de manera indefinida. El tamaño se ajusta exactamente a su número de elementos.

  • Clase Pila y NodoPila.



Los elementos de la pila son los nodos de la lista, con un campo para guardar el elemento y otro de enlace. La clase NodoPila representa un nodo de la lista enlazada. Tiene dos atributos: elemento guarda el elemento de la pila y siguiente contiene la dirección del siguiente nodo de la lista. El constructor pone el dato en elemento e inicializa siguiente a null. El tipo de dato de elemento se corresponde con el tipo de los elementos de la pila, para que no dependa de un tipo concreto; para que sea más gené­ rico se utiliza el tipo Object y de esa forma puede almacenar cualquier tipo de referencia.











La clase PilaLista implementa las operaciones del TAD pila. Además, dispone del atributo cima que es la dirección del primer nodo de la lista. El constructor inicializa la pila vacía (cima == null), realmente, a la condición de lista vacía.











Implementación de las operaciones.

Las operaciones insertar, quitar, cima acceden a la lista directamente con la referencia cima (apunta al último nodo apilado). Entonces, como no necesitan recorrer los nodos de la lista, no dependen del número de nodos, la eficiencia de cada operación es constante, O(1). La clase PilaLista forma parte del mismo paquete que NodoLista, por ello tiene acceso a todos sus miembros. 
Verificación del estado de la pila:
Poner un elemento en la pila. Crea un nuevo nodo con el elemento que se pone en la pila y se enlaza por la cima.
Eliminación del elemento cima. Retorna el elemento cima y lo quita de la pila.

Obtención del elemento cabeza o cima de la pila, sin modificar la pila:

Vaciado de la pila. Libera todos los nodos de que consta la pila. Recorre los n nodos de la lista enlazada, entonces es una operación lineal, O(n).

Tutorial de Pilas.



Tipo abstracto de datos Cola.



Una cola es una estructura de datos que almacena elementos en una lista y permite acceder a los datos por uno de los dos extremos de la lista (figura 36.18). Un elemento se inserta en la cola (parte final) de la lista y se suprime o elimina por el frente (parte inicial, frente) de la lista. Las aplicaciones utilizan una cola para almacenar elementos en su orden de aparición o concurrencia.
Los elementos se eliminan (se quitan) de la cola en el mismo orden en que se almacena, por ello una cola es una estructura de tipo FIFO (first-in/first-out, primero en entra.

Especificaciones del tipo abstracto de datos Cola .

Las operaciones que sirven para definir una cola y poder manipular su contenido son las siguientes: Tipo de dato             Elemento que se almacena en la cola 
Operaciones         
CrearCola                 Inicia la cola como vacía 
Insertar                     Añade un elemento por el final de la cola 
Quitar                       Retira (extrae) el elemento frente de la cola
Cola vacía                Comprobar si la cola no tiene elementos 
Cola llena                 Comprobar si la cola está llena de elementos 
Frente                       Obtiene el elemento frente o primero de la cola 
Tamaño de la cola    Número de elementos máximo que puede contener la cola 

Las colas se implementan utilizando una estructura estática (arreglos), o una estructura dinámica (listas enlazadas, Vector...). Utilizar un arreglo tiene el problema del avance lineal de frente y fin; este avance deja huecos por la izquierda del arreglo. Llega a ocurrir que fin alcanza el índice más alto del arreglo, sin poder añadir nuevos elementos y sin embargo haber posiciones libres a la izquierda de frente.

  • Cola con un arreglo circular .



La forma más eficiente de almacenar una cola en un array es modelar a éste de tal forma que se una el extremo final con el extremo cabeza. Tal arreglo se denomina arreglo circular y permite que la totalidad de sus posiciones se utilicen para almacenar elementos de la cola sin necesidad de desplazar elementos. La figura 36.20 muestra un arreglo circular de n elementos. 
El arreglo se almacena de modo natural en la memoria, como un bloque lineal de n elementos. Se necesitan dos marcadores (apuntadores) frente y fin para indicar, respectivamente, la posición del elemento cabeza y del último elemento puesto en la cola.
El frente siempre contiene la posición del primer elemento de la cola y avanza en el sentido de las agujas del reloj; fin contiene la posición donde se puso el último elemento, también avanza en el sentido del reloj (circularmente a la derecha). La implementación del movimiento circular se realiza según la teoría de los restos, de tal forma que se generen índices de 0 a MAXTAMQ−1: 
Mover fin adelante = (fin + 1) % MAXTAMQ 
Mover frente adelante = (frente + 1) % MAXTAMQ
Los algoritmos que formalizan la gestión de colas en un arreglo circular han de incluir las operaciones básicas del TAD cola; en concreto, las siguientes tareas básicas: 
• Creación de una cola vacía, de tal forma que fin apunte a una posición inmediatamente anterior a frente: frente = 0; fin = MAXTAMQ−1. 
• Comprobar si una cola está vacía: frente == siguiente(fin) 
• Comprobar si una cola está llena. Para diferenciar la condición entre cola llena y cola vacía se sacrifica una posición del arreglo, de tal forma que la capacidad de la cola va a ser MAXTAMQ−1. La condición de cola llena:
frente == siguiente(siguiente(fin))
• Poner un elemento a la cola, si la cola no está llena, avanzar fin a la siguiente posición: fin = (fin + 1) % MAXTAMQ y asignar el elemento. 
• Retirar un elemento de la cola, si la cola no está vacía, quitarlo de la posición frente y avanzar frente a la siguiente posición:(frente + 1) % MAXTAMQ. 
• Obtener el elemento primero de la cola, si la cola no está vacía, sin suprimirlo de la cola.

  • Clase cola con array circular .



La clase declara los apuntadores frente, fin y el arreglo listaCola[ ]. El método siguiente( ) obtiene la posición siguiente de una dada, aplicando la teoría de los restos. A continuación se codifica los métodos que implementan las operaciones del TAD cola. Ahora el tipo de los elementos es Object, de tal forma que se pueda guardar cualquier tipo de elementos.







































  • Cola implementada con una lista enlazada .



La implementación del TAD Cola con una lista enlazada permite ajustar el tamaño exactamente al nú­ mero de elementos de la cola; la lista enlazada crece y decrece según las necesidades, según se incorporen elementos o se retiren. Utiliza dos apuntadores (referencias) para acceder a la lista, frente y fin, que son los extremos por donde salen y por donde se ponen, respectivamente, los elementos de la cola.
La referencia frente apunta al primer elemento de la lista y por tanto de la cola (el primero en ser retirado). La referencia fin apunta al último elemento de la lista y también de la cola.
Declaración de nodo y cola Se utilizan las clases Nodo y ColaLista. El Nodo representa al elemento y al enlace con el siguiente nodo; al crear un Nodo se asigna el elemento y el enlace se pone null. Con el objetivo de generalizar, el elemento se declara de tipo Object. La clase ColaLista define las variables (atributos) de acceso: frente y fin, y las operaciones básicas del TAD cola. El constructor de ColaLista inicializa frente y fin a null, es decir, a la condición cola vacía. 
































Tutorial de Colas.




EJERCICIOS REPASO.

CÓDIGO PILA.

CÓDIGO COLA.


CÓDIGO MAIN.












Diferencia entre Pila y Cola














Ejercicio 1

Problema:
Crear una lista simple la cual debe ingresar números reales, luego ordenarlos de mayor a menor, imprimir la lista, obtener el promedio de los valores de cada lista, comprobar cuál es el valor que más se repite en la lista.

Explicación: Se desarrollaran tres clases una clase Nodo, una Lista y una principal, los nodos deben ser simplemente enlazados dado los requerimientos del usuario. También se puede notar que los nodos deben poseer una variable float en base al problema, el ordenamiento se realizara mediante un método de ordenamiento de los ingresos, la impresión mediante un ciclo repetitivo basado en el tamaño dinámico de la lista, el resto de funciones harán uso de un ciclo similar para su desarrollo con ajustes en base a lo necesitado.

Clase Nodo: Nodos simplemente enlazados


public class Nodo {
private Nodo siguiente;//Lista simplemente enlazada
private float info;

public Nodo(float info,Nodo siguiente){
this.info=info;
this.siguiente=siguiente;
}

public Nodo(float info){
this.info=info;
siguiente=null;
}

public Nodo getSiguiente() {
return siguiente;
}

public void setSiguiente(Nodo siguiente) {
this.siguiente = siguiente;
}

public float getInfo() {
return info;
}

public void setInfo(int info) {
this.info = info;
}


}

Clase lista:


public class Lista {
private Nodo inicio;
private Nodo fin;
public Lista(){
inicio=fin=null;
}
public void imprimirLista(){ //Función que imprime la lista desde su inicio hasta el fin
Nodo aux=inicio;
int cont=1;
while(aux!=null){// Ciclo de repetición que pasa la lista desde inicio a fin 
System.out.println(cont+" "+aux.getInfo());
cont++;//Contador tipo entero para la lista 
aux=aux.getSiguiente();
}
}
public float promedioLista(){ //Función que calcula el prommedio de la lista 
Nodo aux=inicio;
float cont=0;//auxiliar en donde se guardara el valor de cada Nodo
int total=0;//auxiliar en donde se guardara el total de Nodos en la Lista
while(aux!=null){// Ciclo de repetición que pasa la lista desde inicio a fin 
cont=cont+aux.getInfo();
total++;
aux=aux.getSiguiente();
}
return cont/total;
}
public float contador(){//Metodo que cuenta el valor que mas se repite en la lista
Nodo aux=inicio;
int contMay=0,contOtro=0;
float mayor=0,otro=0;
if(aux!=null){//comprueba que la lista no este vacia para hacer referencia a la información del nodo inicio
otro=aux.getInfo();
while(aux!=null){
if(otro==aux.getInfo()){//Si el valor es igual al anterior se mantiene contando
contOtro++;
}else{
if(contMay<=contOtro){//Al variar el valor se hace el cambio de variable en base a si este contador fue mayor al anterior
mayor=otro;
contMay=contOtro;
contOtro=1;//Se inicia en uno, debido a que el valor se calcula en una sentencia anterior
otro=aux.getInfo();
}else{
otro=aux.getInfo();
contOtro=1;
}
}
aux=aux.getSiguiente();
}
}
if(contMay<contOtro){//Se comprueba al final para determinar si el valor enviado es el correcto
return otro;
}
return mayor;
}
public void agregarNodoOrdenado(float info){//Ordena la lista, ingresando cada nuevo Nodo en un posición en base a su valor
Nodo ingreso= new Nodo(info);
if(inicio==null){//si la lista esta vacia
inicio=fin=ingreso;
ingreso.setSiguiente(null);
}else{
if(inicio.getInfo()<=ingreso.getInfo()){//si es menor o igual el valor nuevo al inicio
ingreso.setSiguiente(inicio);
inicio=ingreso;
}else{
if(fin.getInfo()>=ingreso.getInfo()){//Si es menor que el final de la Lista
fin.setSiguiente(ingreso);
fin=ingreso;
}else{
Nodo aux=inicio;
Nodo aux2=inicio.getSiguiente();
while(aux2!=null){//Determina el siguiente valor mas pequeño, va alterando en medio de la lista
if(aux2.getInfo()<ingreso.getInfo()){
break;
}
aux=aux2;
aux2=aux2.getSiguiente();
}
if(aux2.getInfo()<ingreso.getInfo()&&aux2!=null){//Realiza la asignacion del valor obtenido
aux.setSiguiente(ingreso);
ingreso.setSiguiente(aux2);
}
}
}
}
}
}

Clase principal:


import java.util.Scanner;

public class Principal {

public static void main(String[] args) {
// TODO Auto-generated method stub
Lista l=new Lista();
int menu=0;
do{
menu=leerInt("----Menu----"
+ "\n1.Ingresar valor a la tabla"
+ "\n2.Imprimir Lista"
+ "\n3.Calcular promedio"
+ "\n4.Contar mayor numero repetido"
+ "\n0.Salir");
switch(menu){
case 1:{
l.agregarNodoOrdenado(leerFloat("Ingrese el valor del nodo"));
break;
}
case 2:{
l.imprimirLista();
break;
}
case 3:{
System.out.println("El promedio de la lista es de "+l.promedioLista());
break;
}
case 4:{
System.out.println("El valor que mas se repite en la base de datos es: "+l.contador());
break;
}
case 0:{
System.out.println("Programa Terminado");
break;
}
}
}while(menu!=0);
}
public static int leerInt(String texto){
Scanner leer=new Scanner(System.in);
System.out.println(texto);
return leer.nextInt();
}

public static float leerFloat(String texto){
Scanner leer=new Scanner(System.in);
System.out.println(texto);
return leer.nextFloat();
}
}


Ejercicio 2


Problema: Crear una lista simple enlazada de números enteros, se desea añadir un nodo entre dos nodos consecutivos; el dato del nuevo nodo debe ser la diferencia en valor absoluto de los dos nodos.

Ejemplo si tengo la siguiente lista
 |   20   |   |   43   |  |   17   |  |   4    |  |    11   |
Se dese insertar un dato entre 43 y 17.
Reviso que exista la secuencia
Luego calculo el valor absoluto de (43-17)
Inserto entre esos elementos.
 |   20   |   |   43   |  |   26  |  |   17   |  |   4    |  |    11   |


Explicación: Se generara un clase lista simple en la cual los nodos tengan como parámetro un valor entero y una referencia al nodo siguiente. En base a esta Lista se generara un método capaz de encontrar un valor dado en este caso por un entero y generar entre dichos nodos un nuevo nodo cuyo dato entero sea el valor absoluto de las diferencia entre estos valores.

Para generar dicho método se hará uso de un contado el cual mantenga constancia del numero de nodos en la lista, y se generara el nuevo nodo después del nodo indicado, para el calculo de los valores se usara el método abs de la clase Math.Como dato final se decidió obviar el calculo después del ultimo dato debido a la falta de un segundo dato para el calculo del valor absoluto.

Clase Nodo


public class Nodo {
private Nodo siguiente;
private int info;
public Nodo(int info) {
this.info = info;
}
public Nodo(Nodo siguiente, int info) {
this.siguiente = siguiente;
this.info = info;
}
public Nodo getSiguiente() {
return siguiente;
}
public void setSiguiente(Nodo siguiente) {
this.siguiente = siguiente;
}
public int getInfo() {
return info;
}
public void setInfo(int info) {
this.info = info;
}
}

Clase Lista

public class Lista {
private Nodo inicio;
private Nodo fin;
public Lista(){
inicio=fin=null;
}
public void imprimir(){
Nodo aux=inicio;
int cont=1;
while(aux!=null){
System.out.println(cont+" "+aux.getInfo());
cont++;
aux=aux.getSiguiente();
}
}
public void agregarNodo(int valor){//Funcion basica para agregar un valor al final de un lista simple
Nodo nuevo= new Nodo(valor);
if(fin!=null){
fin.setSiguiente(nuevo);
}else{
inicio=nuevo;
}
fin=nuevo;
}
public void agregarValor(int pos){
int cont=1;
Nodo aux=inicio;
Nodo aux2=inicio.getSiguiente();
if(pos<cont()&&pos>1){//Se controla que el numero ingresado sea valido para la ejecucion de la aplicacion.
while(aux2!=null){//se controla en base a la cual se mas posible llegue a ser un valor nulo
if(cont==pos){//si se encuentra un valor igual al especificado se rompe el ciclo
break;
}
cont++;
aux=aux2;
aux2=aux2.getSiguiente();
}
if(cont==pos&&aux2!=null){//Si los valores son iguales se agrega el valor absoluto entre los dos nodos.
Nodo nuevo=new Nodo(Math.abs(aux.getInfo()-aux2.getInfo()));
aux.setSiguiente(nuevo);
nuevo.setSiguiente(aux2);
}
}
}
public int cont(){//Realiza el calculo del numero total de valores de la lista
Nodo aux=inicio;
int cont=0;
while(aux!=null){
cont++;
aux=aux.getSiguiente();
}
return cont;
}
}

Clase Principal

import java.util.Scanner;

public class Principal {

public static void main(String[] args) {
// TODO Auto-generated method stub
Lista l=new Lista();
int menu=0,aux;
do{
menu=leerInt("----Menu----"
+ "\n0.Salir"
+ "\n1.Agregar Entero a la Lista"
+ "\n2.Imprimir Lista"
+ "\n3.Agregar un valor absoluto despues del Nodo");
switch(menu){
case 0:{
System.out.println("Programa Terminado");
break;
}
case 1:{
l.agregarNodo(leerInt("Ingrese el valor a agregar a la lista"));
break;
}
case 2:{
l.imprimir();
break;
}
case 3:{
aux=leerInt("Ingrese la posicion despues de la cual se agregara el valor absoluto");
if(aux>=l.cont()||aux<1){//Se limita el ingreso para tener dos valores entre los cuales ingresar el nuevo dato
System.out.println("Valor fuera del rango de la lista");
}else{
l.agregarValor(aux);
System.out.println("Valor agregado a la lista");
}
break;
}
}
}while(menu!=0);
}
public static int leerInt(String texto){
Scanner leer= new Scanner(System.in);
System.out.println(texto);
return leer.nextInt();
}
}


Ejercicio 3

Escribir un programa para obtener una lista doblemente enlazada con los caracteres de 
una cadena leída desde el teclado. Cada nodo de la lista tendrá un carácter. Una vez que 
se haya creado la lista, ordenarla alfabéticamente y escribirla en pantalla

Explicación:
El uso de listas doblemente enlazadas facilitan la búsqueda de valores y la referencia a 
elementos con respecto a sus nodos.

Para la comparación de caracteres se hará uso de la Clase Character por su facilidad al 
permitir el uso de 
funciones como: compareTo, la cual se utilizara en el ordenamiento de la lista.

Se hará uso de una función organizadora de los ingresos para evitar problemas con 
la alteración del orden de los nodos.

Clase NODO:

public clss Nodo {
private Nodo anterior;
private Nodo siguiente;//Al ser doblemente enlazadas contiene una referencia a un nodo anterior y siguiente.
private Character info;//La clase Character funciona similar a un char pero permite el uso de funciones
public Nodo(Nodo anterior, Nodo siguiente, char info) {
this.anterior = anterior;
this.siguiente = siguiente;
this.info = info;
}
public Nodo(char info) {
anterior=siguiente=null;
this.info = info;
}
public Nodo getAnterior() {
return anterior;
}
public void setAnterior(Nodo anterior) {
this.anterior = anterior;
}
public Nodo getSiguiente() {
return siguiente;
}
public void setSiguiente(Nodo siguiente) {
this.siguiente = siguiente;
}
public char getInfo() {
return info;
}
public void setInfo(char info) {
this.info = info;
}
}

Clase LISTA:

public class Lista {
public Nodo inicio;
public Nodo fin;
public Lista(){
inicio=fin=null;
}
public void iniciar(String texto){
inicio=fin=null;//En caso de usarse nuevamente, se borra el contenido de la Lista anterior
Nodo nuevo;
int i;
for(i=0;i<texto.length();i++){
agregarOrdenado(texto.charAt(i));//Agrega los valores del String en orden al momento de inicializar
}
}
public void agregarNodo(char a){//Funcion que agrega un Nodo al final de la lista
Nodo nuevo=new Nodo(fin,null,a);
if(fin!=null){
fin.setSiguiente(nuevo);
fin=nuevo;
}else{
inicio=fin=nuevo;
}
}
public void imprimir(){//Funcion que imprime la Lista de inicio a fin
Nodo aux=inicio;
int cont=1;
while(aux!=null){
System.out.println(cont+""+aux.getInfo());
cont++;
aux=aux.getSiguiente();
}
}
public void agregarOrdenado(Character valor){//Funcion que agrega un nodo a lista alfabéticamente a-z
Nodo nuevo=new Nodo(valor);
if(inicio==null){//Compara si la lista esta vacia
agregarNodo(valor);
}else{
if(valor.compareTo(inicio.getInfo())<=0){//Compara si el caracter es menor que el inicio a<z
nuevo.setSiguiente(inicio);
inicio.setAnterior(nuevo);
inicio=nuevo;
}else{
if(valor.compareTo(fin.getInfo())>=0){//compara si el caracter es mayor que el fin z>a
agregarNodo(valor);
}else{
Nodo aux=inicio;
while(aux.getSiguiente()!=null){
if(valor.compareTo(aux.getSiguiente().getInfo())<0){//Busca en la lista hasta su final un valor mayor que el del caracter para su ingreso
break;
}
aux=aux.getSiguiente();
}if(aux.getSiguiente()!=null){//Si existe el valor esperado
if(valor.compareTo(aux.getSiguiente().getInfo())<0){//Se ingresa el valor a la lista y se realizan las conecciones necesarias
nuevo.setAnterior(aux);
nuevo.setSiguiente(aux.getSiguiente());
aux.getSiguiente().setAnterior(nuevo);
aux.setSiguiente(nuevo);
}
}
}
}
}
}
}


Clase Principal:

import java.util.Scanner;

public class Principal {

public static void main(String[] args) {
// TODO Auto-generated method stub
Lista l=new Lista();
int menu=0;
do{
menu=leerInt("----Menu----"
+ "\n0.Salir"
+ "\n1.Generar Lista en base a una cadena de caracteres"
+ "\n2.Imprimir Lista");
switch(menu){
case 0:{
System.out.println("Programa Terminado");
break;
}
case 1:{
l.iniciar(leerString("Ingrese la palabra para generar la lista"));
break;
}
case 2:{
l.imprimir();
break;
}
}
}while(menu!=0);
}
public static int leerInt(String texto){
Scanner leer=new Scanner(System.in);
System.out.println(texto);
return leer.nextInt();
}

public static String leerString(String texto){
Scanner leer=new Scanner(System.in);
System.out.println(texto);
return leer.nextLine();
}
}