Programando en Linux: Listas enlazadas simples.

Java es un lenguaje que posee una extensa variedad de clases, entre ellas podemos encontrar las famosas colecciones de estructuras, mismas que están compuestas por listas enlazadas, pilas entre otras; lo cual si bien es cierto cumplen con todo lo que necesitamos a la hora de programar, no son validas para realizar las asignaturas en cursos universitarios o de técnicos en programación, en los cuales se prioriza el entendimiento sobre como funcionan estás estructuras de datos. Por todo lo anterior, hoy les traigo un tutorial sobre listas enlazadas, en el cual cubriré los conceptos básicos, como se construyen (a “mano”) y por supuesto, como usarlas en una aplicación.

 

¿Qué es una lista enlazada?

Podemos decir que una lista enlazada no es otra cosa que una cadena, en la cual cada uno de sus elementos está enlazado al siguiente mediante una conexión, en nuestra caso una dirección de memoria.

Pero vamos un poco más despacio, pensemos en una cadena común, de esas que se utilizan para asegurar portones, vemos en ella un conjunto de elementos conectados llamados eslabones, dichos eslabones son los que conforman la cadena y si uno de ellos pierde su conexión con el siguiente, entonces la cadena se rompe; de igual forma  en una lista enlazada, cada eslabón (llamado nodo, tradicionalmente) está conectado al siguiente y es este conjunto de nodos son los que conforman la lista, si uno de ellos pierde su conexión con el siguiente, entonces jamás podremos acceder a los nodos posteriores.

nicubunu_Chain¿Qué elementos conforman una lista enlazada?

Como mencioné recién, una lista enlazada está compuesta por eslabones llamados nodos, estos nodos están conectados mediante referencias a direcciones de memoria, pero debemos hablar sobre un eslabón muy importante, el primero que conforma la lista, hace poco dije que si un nodo pierde su conexión con el siguiente entonces  sería imposible acceder a los nodos posteriores, por lo tanto y por sentido común, notamos que si se pierde la dirección del primer elemento, la lista completa quedará inaccesible, así que el nodo más importante en nuestra lista es sin lugar a dudas el primero que la conforma.

A su vez, cada nodo está conformado por dos partes, la primera llamada parte de datos es la que permite almacenar lo que el programador desea guardar, por ejemplo un String, un Int, e inclusive una clase, y la segunda la dirección de memoria de la que tanto he hablado.

NodoAhora bien, para crear un nodo necesitamos crear una clase que contenga estos dos elementos y luego naturalmente un objeto para manipular la lista.

¿Qué  operaciones se pueden realizar sobre una lista enlazada?

Las operaciones básicas en una lista son 4:

  1. Insertar un elemento
  2. Mostrar la lista completa
  3. Buscar y (mostrar o modificar) un elemento
  4. Eliminar un elemento
 Manos a la obra:

En este tutorial veremos las dos primeras operaciones, Insertar un elemento y Mostrar el contenido de la lista, pero antes de pasar al código necesitamos entender el fundamento de cada operación.

Insertar un elemento en una lista enlazada:

Para insertar un elemento dentro de una lista enlaza, primero debemos entender que sucede con la lista, es decir, requerimos conocer el estado de la lista (si está vacía o por el contrario si posee elementos).

En caso de que la lista esté vacía procederemos de la siguiente manera:

  1. ElementoaInsertar.siguiente = nada
  2. PrimerElemento = ElementoaInsertar

Insertar_primerNodoComo notamos en la imagen, el primer elemento en realidad es una referencia y no un nodo como tal, en otras palabras, no contiene una parte de datos, pues su propósito como mencioné antes, es el de mantener la referencia de memoria para acceder a los nodos posteriores. Si se quiere puede tomarse al primer elemento como un nodo sin su parte de datos.

En caso de que la lista sí contenga elementos, entonces se procede como sigue:

Necesitamos establecer si vamos a insertar al inicio de la lista o al final, la diferencia radica en el orden que se apilan los nodos, de modo que si escogemos insertar al inicio, el último nodo insertado será el primero en ser recorrido (mostrado) mientras que  si insertamos al final de la lista,  mantendríamos  cierto orden lógico.

Insertar al inicio de la lista:

  1. ElementoaInsertar.siguiente = primerElemento
  2. primerElemento = ElementoaInsertar

 

Insertar_primer_elemento_inicioLa imagen nos dice lo siguiente: Toma el nodo a insertar y haz que su parte de dirección apunte hacía donde apunta el primer elemento, esto con el propósito de enganchar el nuevo elemento a la lista. Segundo, toma el primer elemento y colócalo apuntando a la dirección de nuevo elemento, con esto logramos actualizar el valor de dirección del primer elemento que se colocaría en apuntando al nodo recién insertado.

 Ahora que entendemos los conceptos de inserción procedemos a ver un poco del código en Java.

Primero necesitamos crear una clase Nodo, en la cual procedemos a declarar dos atributos, uno del mismo tipo de la clase, que será en el que guardemos la dirección de memoria, y el otro del tipo de dato deseado, ya sea un tipo primitivo o una clase.

public class Nodo{
  int numero;
  Nodo siguiente;
public Nodo (int nuevoNumero){
   this.numero = nuevoNumero;
   this.siguiente = null;
}
}

Posteriormente creamos una clase con los métodos de la lista, primeramente el de insertar, luego el de mostrar; es importante aclarar que estas dos clases deben ir en el mismo paquete de Java, por lógica y por comodidad.

public class Lista{

 Nodo primerElemento;
  public Lista(){
  this.primerElemento = null;

}
public void insertar(int nuevoNumero){

   Nodo nuevoElemento = new Nodo(nuevoNumero);

   if (primerElemento == null){
       nuevoElemento.siguiente = null;
       primerElemento = nuevoElemento;
  }
   else{
       nuevoElemento.siguiente = primerElemento;
       primerElemento = nuevoElemento;
    }
}
}

Repasando de nuevo los elementos de esta clase:

El constructor de la clase Lista es llamado cuando se crea el objeto en cualquier otra parte del código para el usuario, dicho constructor es usado una vez para crear una instancia de la lista, por lo tanto en ese momento el primer elemento se inicializa en null, luego cuando el dato es obtenido del usuario y se desea insertar en la lista, se llama al método insertar, seguidamente se verifica si la lista está vacía, si lo está, entonces ejecuta el código del IF, en caso contrario, ejecuta el código del Else, ambos códigos ya fueron explicados conceptualmente por lo que no debería ser nada complicado entenderlos.

 Bien, ahora vamos a implementar nuestro código para ver que todo funcione correctamente, para ello escribimos una clase main en la cual instanciaremos un objeto de tipo Lista, que utilice el método insertar de dicha clase:

import javax.swing.JOptionPane;
public class Main {
    
    public static void main (String args[]) {
        Lista nuevaLista = new Lista();
        String opcion = "";
        
        
        while(!opcion.equals("3")){      
             nuevaLista.insertar(Integer.parseInt(JOptionPane.showInputDialog(null,"Escriba un número")));
             opcion = JOptionPane.showInputDialog(null, "Escriba 3 para salir, o cualquiera para continuar");
        }
    }
}

 

Esta clase Main es bastante sencilla, su finalidad es la de crear un objeto para poder utilizar el método insertar de la clase Lista, para lo cual se vale de un while que ejecuta el código dentro de el mientras se cumpla la condición establecida, opción distinta de 3.

Note como no necesitamos importar la clase Lista, más arriba mencioné que por comodidad nos convenía colocar todo en el mismo paquete Java, pues bien, esta es una de las razones; en caso contrario si lo hubiéramos colocado en un paquete distinto, entonces por obligación tendríamos que declarar el import.

 Mostrar los elementos de la lista:

Bien el procedimiento para mostrar los datos almacenados en una lista enlazada es muy simple, basta con recorrer cada uno de sus elementos mientras  no sea igual a Null, es decir, vacío.

A su vez para cada elemento recorrido mostraremos su valor y lo concatenaremos con el resto.

Definamos el método mostrar en la clase Lista:

public String mostrar(){
        Nodo auxiliar = primerElemento;
        String numeros = "";
        
        while(auxiliar != null){
                numeros += auxiliar.numero;
                auxiliar = auxiliar.siguiente;
            }
        return numeros;
    }

Lo que hace este método es concatenar cada elemento de la lista en un String llamado números, para posteriormente ser retornado al objeto que lo invoca dentro de la clase main.

Vemos que, Auxiliar nos permite iniciar desde la posición uno e ir efectuando el recorrido mientras no se haya llegado al final de la lista, mismo que está indicado por NULL; como ven es muy simple.

Para utilizarlo basta con crear un objeto JOptionPane dentro de main y mandarle los valores de retorno del método:

JOptionPane.showMessageDialog(null,nuevaLista.mostrar());

Esta última porción de código la debemos colocar fuera del While presente en la clase Main, puesto que así se ejecutará cuando se haya terminado de definir la lista.

Este ha sido el primer tutorial sobre listas enlazadas espero les sea de ayuda; ante cualquier duda o inconveniente no duden en comentar. Saludos y un abrazo.

Anuncios

JGpg mi gestor para cifrar archivos mediante GPG

Primero deseo pedir disculpas a mis lectores, he pasado un poco ocupado con muchos trabajos y no he tenido tiempo para responder preguntas, ni mucho menos para actualizar el blog, por otra parte como para mi lo importante no es la cantidad sino la calidad, no puedo pasar por acá escribiendo cualquier sandez, así que de nuevo les ruego me perdonen.

Bien el motivo para esta entrada ha sido la interfaz construida en java, que recién programé para cifrar archivos mediante GPG, sí yo sé, existen muchas aplicaciones de calidad que pueden lograr esto, sin embargo, la mía fue concebida con fines puramente didácticos, lo que no excluye claro está, que algunos de ustedes la encuentren útil y hasta curiosa.

Fue escrita en java, su intensión como lo dije, es facilitar el uso de GPG, así que en pocas palabras es tan sólo una “interfaz gráfica de usuario”, para usarla van a requerir tener previamente instalado el JRE o el Open JRE, cosa que se logra fácilmente en cualquier distribución  Gnu/Linux.

Algunos cambios en la aplicación (La parte para el descifrado está en “implementación” :P)

JGpg-1.0.1

Enlace para descarga de la versión 1.0.1

Esta es la interfaz

JGpg
Ahora si alguno de ustedes se anima a probarla y a comunicarme sus errores o algo que deseen implementar, no duden en comunicármelo, repito esto es para mi un hobby pero cualquier tipo de crítica es bienvenida y tengan la seguridad de que mejoraré la aplicación.

Sin más que decir, les dejo el link para que la prueben.

https://dl.dropboxusercontent.com/u/68911480/JGpg.jar

Introducción a la programación en C++ linux Codeblocks

Selección_014

Esta es tan solo una entrada de complemento para el post Introducción a la programación en C++ linux   y tiene como función implementar el código expuesto, dentro de nuestro IDE Codeblocks.

Se supone que para este punto ya tienes que haber descargado codeblocks, sino es así descárgalo del siguiente enlace:

http://www.codeblocks.org/downloads/26

Ahora abriremos el IDE y empezaremos.

Code::Blocks 12.11_007como pueden ver en la imagen nos vamos al menú File-New-File  y nos saldrá un cuadro pidiendo el tipo de archivo que deseamos, para nuestro caso usaremos un archivo en blanco o empy file.

Code::Blocks 12.11_008Luego viene el siguiente recuadro, el cual nos pedirá el nombre del directorio en donde guardaremos nuestro programa.

Empty file_009Hacemos clic en el cuadrito  “..” y nos saldrá.

Select filename_010En esta ventana como ven escogemos el directorio y le colocamos un nombre  a nuestro programa, en este caso mi_primer_programa.cpp, ojo que la terminación .cpp es muy importante escribirla, luego guardamos y regresamos al recuadro anterior.

Empty file_011Finalizamos y se nos mostrará el editor de texto en blanco, en el cual pegaremos el código de la entrada anterior.

mi_primer_programa.cpp - Code::Blocks 12.11_012Una vez copiado el código, compilaremos, haciendo uso de los botones correspondientes, fíjate en la imagen de arriba. Entonces le damos clic al botón 1 y luego al botón 2.

-home-cooper15-programas-C++-mi_primer_programa_013

Por último veremos nuestro programa ejecutado y eso es todo.

Cualquier duda que tengan no duden en comentar…

Introducción a la programación en C++ linux (también sirve en windows)

source_c++

Algunas observaciones:

C++ es un lenguaje de alto nivel y base fundamental de sistemas operativos y también de poderosos toolkits para componentes gráficos, como por ejemplo QT.  C++ es un lenguaje que lógicamente puede ser ejecutado tanto en windows como en linux sin que haya ningún problema (siempre y cuando se usen las librerías propias del lenguaje).

Código fuente:

El código fuente lo conforman el conjunto de instrucciones escritas por el programador  en un fichero de texto, a su vez estas instrucciones serán ejecutadas al pie de la letra por el programa resultante.

IDEs y Compiladores:

Dicho en palabras sencillas, un compilador es un programa o aplicación que traduce el código fuente escrito por el programador a un lenguaje que la máquina entienda y pueda ejecutar, posterior a su compilación el programa podrá ser ejecutado si no existen errores sintácticos dentro del código fuente, ejemplos: g++(compilador libre y actualizado), borland compiler (privativo y no actualizado).

Un IDE, Entorno  de Desarrollo Integrado, es como su nombre lo indica, una aplicación cuya función primordial es la proveer al programador de todas las herramientas necesarias para su trabajo en un solo ambiente, en otras palabras, es lo mismo que colocar las herramientas independientes en un mismo lugar, facilitando así la tarea del programador. Algunos componentes del IDE son depurador,compilador,editor de texto (donde se escribe el código fuente), ejemplos: dev c++,codeblocks, codelite, netbeans, eclipse.

Codeblocks:

Codeblocks es un IDE el cual cuenta a su vez con el compilador libre  g++ que a su vez forma parte del conjunto de compiladores GNU, codeblocks nos facilita la programación de nuestras aplicaciones en c++, además es multi plataforma por lo que existen versiones tanto para Windows como para Linux, este es el IDE que recomiendo para los ejemplos y lo pueden descargar del siguiente enlace:

http://www.codeblocks.org/downloads/26

A programar, pero antes…

Es importante para garantizar la portabilidad de aplicaciones entre windows y linux seguir algunas de las siguientes recomendaciones:

  1. En la medida de lo posible no utilizar bibliotecas propietarias o exclusivas del compilador, tales como conio.h y cualquier otra que no forme parte del standard C++.
  2. Siempre usar un compilador actualizado con las ultimas modificaciones del standard C++.
  3. Evitar el uso de código deprecated u obsoleto, por ejemplo evitar la función gets.
  4. Tener cuidado con las llamadas al sistema por ejemplo: para limpiar pantalla en windows es system(“CLS”); mientras que en linux es system(“clear”);
  5. Siempre usar la documentación oficial para c++ o en su defecto libros y manuales actualizados, no anteriores al año 2000.

Manos a la obra:

Un primo me pidió que le ayudara con una tarea y pues la mejor forma es explicar paso a paso, además le puede ser útil a mucha mas gente, así que empecemos por plantear el problema:

Problema:

El problema consiste en escribir un programa que reciba mediante el teclado dos números, que a su vez serán enviados a una función, la cual los sumará y retornará el resultado.

Parte por parte:

primero veamos algo sencillo


#include<iostream>

using std::cout;
using std::cin;
using std::endl;

int main ()
{
    int primerNumero, segundoNumero;

      cout<<"digite el primer numero"<<endl;
         cin>>primerNumero;
      cout<<"digite el segundo numero"<<endl;
         cin>>segundoNumero;

     cout <<"primer numero es: "<<primerNumero<<endl;
     cout<<"segundo numero es:"<<segundoNumero<<endl;

    return 0; // siempre devuelve 0
}

Ahora repasemos linea por linea lo que significa esto. En primer lugar tenemos la cabecera o biblioteca que necesitamos incluir dentro de nuestro programa, en este caso, #include<iostream> significa incluya la biblioteca iostream de entrada y salida, la cual nos permitirá la entrada de valores por parte del usuario y su correspondiente salida por la pantalla.

Seguimos con la instrucción using la cual como su nombre lo indica le dice a nuestro programa, que use la instrucción cout,cin y endl, que están dentro del espacio de nombre std y que a su vez pertenecen a la biblioteca iostream, con lo cual se nos permitirá su uso. si se desea ampliar un poco más sobre este punto puede buscar en manuales de c++.

cout:

permite desplegar en pantalla el valor dentro de una variable o un texto entre comillas indicado por el programador, la sintaxis de uso es la siguiente:

cout<<"texto"<<valorDeVariable;

es importante recalcar que después de cada valor desplegado deben ir los siguientes caracteres << a no ser que ya no se desee incluir nada más y se termina la instrucción con un punto y coma.

endl:

endl es una instrucción sencilla que nos permite mantener la legibilidad y estética de las salidas de texto, su función es simplemente decirle al programa se acabo la linea, la próxima vez que escriba empezará en una nueva. Ejemplo sin endl:

cout<<"texto1";
cout<<"texto2";

lo anterior hará que la salida en pantalla luzca así:

texto1texto2

Ahora un ejemplo con endl:

cout<<"texto1"<<endl;
cout<<"texto2"<<endl;

y obtendríamos una salida así:

texto1
texto2

cin:

Por último la instrucción cin,  nos permite introducir valores por teclado dentro de nuestro programa, cin es particularmente usada para introducir valores numéricos y no cadenas de caracteres como por ejemplo un nombre completo. Ejemplo:

cin>>variable;

su uso es simple, nada más escribimos cin seguida de los caracteres >> y el nombre de la variable que deseamos llenar con un valor del teclado.

Función main:

Es prácticamente una función que siempre debe ir en nuestro programa lo ideal es declararla como entera anteponiéndole el identificador int, ya que al final del main retornara un valor 0, lo ideal es que main no este muy recargada y generalmente se usa para llamar a otras funciones declaradas por el programador.Su sintaxis es la siguiente:

int main()
{
   aquí va el código...
   ....
   ....
   return 0;
}

Funciones declaradas por el programador:

Una función es simplemente una porción de código  dedicada a realizar alguna tarea especifica o subrutina que se repite más de una vez en nuestro programa, son ideales para dividir una gran tarea en otras más pequeñas, de modo que simplifica el trabajo.

Las funciones pueden ser de distintos tipos y devolver algún valor por ejemplo, int,double, char, float, etc; o también pueden no retornar un simple valor, en cuyo caso el identificador usado será void.

A las funciones también se les pasan argumentos, a los cuales se les llama parámetros, estos van incluidos dentro del paréntesis respectivo de la función a la que se le envían.

Ejemplo función que retorna un valor

  int funcion(int a, int b)
  {
     int c=a +b;
     return(c);
  }

como vemos esta función recibe el valor de dos parámetros y los coloca dentro de a y b, luego suma estos números y posteriormente retorna el valor resultante.

dentro del main la llamada a esta función ocupa ser igualada a una variable del mismo tipo en este caso int (entera) para poder “almacenar” el valor que le fue enviado desde la función y además se le pasan los números correspondientes. Quedaría así:

int resultado = funcion (primerNumero,segundoNumero);

El ejemplo propuesto:

Retomando el problema principal, ahora que hemos aclarado las partes del programa podemos pasar al problema que propuse, de modo que el código quedaría así:

#include<iostream>

using std::cin;
using std::cout;
using std::endl;

int llamada (int x, int y)

{

    int suma; // variable local resuldato suma
    suma = x+y;

    return (suma); // envia suma que será igualada a resultado en main

}

int main ()
{

    cout << "vamos a llamar a la funcion" <<endl;

    // crea dos variables para pasarle los parametros

    int numero1,numero2;

    cout<<"Digite primer numero"<<endl;
      cin>>numero1;                     // se inserta desde el teclado el primer numero.

    cout<<"Digite segundo numero"<<endl;
      cin>>numero2;

    int resultado = llamada(numero1,numero2); // envia parametros para sumar y recibe el resultado.
    cout << "resultado es: "<<resultado<<endl;
    return (0);

}

Bien, a grandes rasgos el programa ya ha sido evaluado casi en su totalidad, pero no está de más recalcar los puntos.

En primer lugar la función llamada se encarga de sumar los dos números que le suministramos y que fueron ingresados mediantes las instrucciones cin en sus variables respectivas, posteriormente la función llamada suma esos valores y los retorna, de modo que se almacena en resultado y por último se despliega dicha suma con un cout.

Implementación en codeblocks:

Implementación del código en Codeblocks

Fuentes:

Documentación oficial c++:
http://www.cplusplus.com/

C con clase(apartado de funciones):
http://c.conclase.net/curso/?cap=015

Script para formatear tu dispositivo USB (Linux)

usb

Ya lo publique en espacio linux, sin embargo no puede faltar en mi blog y es que en estos días ando inspirado haciendo y deshaciendo, está vez me dio por realizar una tarea que tenía pendiente casi desde que llegue a linux, programar una utilidad para dar formato a dispositivos y memorias usb, en breve les presentaré los resultados.

El porqué:

La pregunta salta a la vista ¿Por qué reinventar la rueda? si existen tantas herramientas tales como Gparted o simplemente usar la linea de comandos en dos toques  listo, pues muy bien, la razón principal es que en ambos casos se puede complicar la operación si no tenemos el debido cuidado, por ejemplo en Gparted ocupamos escoger el dispositivo correcto y con mkfs  un error al colocar la instrucción puede resultar desastroso, además con esta última opción primero debemos averiguar información del dispositivo tal como la partición correspondiente, cosas por las que un usuario normal no tiene necesidad de preocuparse.

Es por lo anterior que decidí simplemente hacer más sencilla esta tarea tan común para cualquier usuario mediante el script que les traigo en esta ocasión, sin embargo debo aclarar que dicho script emplea mkfs, la ventaja es que el usuario no se entera de este detalle, pues el programa cumple la función de asistente de formateo.

Como usarlo:

Notas aclaratorias versión 0.2

  • Debe ser ejecutado como súper usuario
  • El dispositivo debe ser montado por el usuario, una forma es abriéndolo desde el navegador de archivos.
  • Removida la opción de tamaño máximo y por ende la confirmación.
  • requiere tener mkfs.

Notas aclaratorias versión 0.1:

  • El dispositivo debe estar montado.
  • Por seguridad sólo reconoce dispositivos con formato anterior fat y fat32.
  • Por seguridad pide confirmación si el dispositivo es mayor a 16 GB.
  • Requiere tener instalado mkfs.

En primera instancia nos bajamos el script (la versión más resiente es la 0.2) del siguiente enlace:

https://www.dropbox.com/s/co6nc396pff9dpe/formatear_llave.sh versión 0.2

https://dl.dropboxusercontent.com/u/68911480/Script_Formatear.zip  versión 0.1

Lo descomprimimos y leemos las instrucciones, pero sólo por si acaso, también las detallo aquí.

Copiamos el script en nuestro directorio /home/TU_USUARIO

le damos permisos de ejecución:

chmod +x formatear_llave.sh

Nos logeamos como superusuario escribiendo su seguido de nuestra contraseña.

su
"escribes tu contraseña"

Ejecutamos el script así:

./formatear_llave.sh

Luego simplemente sigues las instrucciones del script y al final tendrás tu memoria usb,pendrive o como gustes llamarle, formateado y listo para ser usado.

Nota: El script funciona perfectamente en debian y derivados, en otras distribuciones podría no funcionar, si tienes alguna corrección o sugerencia puedes hacerla en los comentarios o enviándome un correo (más información en contacto).

Y ahora, espero les sea de mucha utilidad y cualquier inconveniente o bug no duden en comentar que con gusto trataremos de darle solución.

Programando en linux: Pilas y colas en JAVA

Como muchos sabrán, Java es multi-plataforma lo que significa que puede ser ejecutado en distintos computadores, con prestaciones distintas y sistemas operativos variados sin que ello afecte el funcionamiento especifico del programa que hayamos escrito. En pocas palabras lo anterior quiere decir que el programa que hemos escrito en windows correrá perfectamente en linux, sin que tengamos que cambiar absolutamente nada esto nos facilita la vida y por supuesto es un seguro para aquellas personas que aun le tienen miedo a la programación en linux.

Bien hecha esta aclaración, vamos a ver como manipular una pila desde una cola, este ejercicio se me presento en mi curso de algoritmos y creo que será interesante compartirlo con la comunidad, así que empezamos.

¿Qué es una Pila?:
En palabras sencillas, una pila es una estructura dinámica que tiene la particularidad la siguiente particularidad, el último elemento que entra en ella es el primero en salir, por ejemplo supongamos que tenemos una torre de 5 libros, en ella el último libro que colocamos (el de la cima) debe ser el primero que debemos quitar para acceder al cuarto y así sucesivamente hasta llegar al primer libro; de modo que en una pila siempre vamos quitando el elemento que fue insertado al final, cabe destacar que los elementos que salen dejan de formar parte de la estructura.

¿Qué es una cola?:
Una cola es otra estructura dinámica, en la cual el primer elemento en ser insertado es el primer elemento en ser sacado de la estructura, una cola es cotidianamente lo que hacemos cuando vamos a una oficina a realizar un trámite y nos acomodamos en orden de llegada, de modo que el primer sujeto en ser atendido es el primero en haber llegado y el último en realizar el trámite es último en formar parte de la cola.

Descripción del problema:

En un supermercado hay 10 cajas registradoras, en cada una de las cuales se colocan los clientes con sus carros de la compra en orden de llegada. Por cada caja registradora queremos guardar el nombre de la cajera, la recaudación acumulada y los carros en espera.

Por otro lado. En cada carro se amontonan los distintos productos, de modo que tan solo puede añadirse o extraerse el situado en la parte superior. Por cada producto guardamos su nombre y precio.

Analizando el problema:
Parte de darle solución al enunciado consiste primero en desmenuzar los componentes que lo conforman, así por ejemplo vemos que los productos se extraen de arriba hacia abajo, es decir, la extracción de productos sugiere que cada producto en la cima del carro de compras es procesado por la cajera y entonces nos viene a la mente la idea de una pila de productos.

A su vez, los carritos de compras son atendidos en orden de llegada, esto quiere decir que el primer cliente en llegar a la caja, es el primer cliente en ser atendido y en salir del almacén, todo esto nos trae a la mente la noción de cola, por lo tanto debemos pensar en la creación de una cola de carros de compra.

Luego tenemos las 10 cajas registradoras que evidentemente pueden formarse con un arreglo, puesto que de antemano conocemos su cantidad.

Y por último debemos establecer la relación existente entre todas estas estructuras, primero las cajas atienden carros, por tanto deberemos ligar la cola de carros a una caja especifica dentro de las 10, luego cada carro posee una pila de productos de modo que tendremos que considerar crear una pila de productos para cada carrito de compras, pero a todo esto nos surge una interrogante en nuestra mente.

¿Cómo meto una cola dentro de un arreglo y una pila dentro de una cola?
la respuesta es sencilla, resulta  imposible realizar estas operaciones, sin embargo lo que si podemos es crear cada estructura por separado y crear enlaces adecuados que nos permitan manipular referencias especificas a cada una de estas estructuras, de modo que al final tendremos una sola caja con su respectiva referencia a una sola cola de carros, dentro del cual, cada uno de ellos referencia a una sola pila de productos.

Creando la clase Carro con atributos productos:

Bien esta clase Carro implementa dos procedimientos interesantes, el primero llenaProductos, se encarga de pedir el nombre y el precio de un producto al operario y además recibe un objeto de tipo pila que es enviado desde otra clase, luego está parte es importante, ese objeto de tipo pila será el encargado de introducir nuestro producto una vez ingresados los datos dentro de la pila y para ello hace uso de pp.insertaP(nombreProducto,precioProducto);

Clase CajaRegistradora:

Y aquí viene la magia de este ejercicio, esta clase es la encargada de “llenar” cada carro con sus respectivos productos, veamos:

CapturaCR se encarga de insertar los carros en la cola y consecuentemente los productos, mediante una referencia, es decir, llenaproductos crea un objeto de la clase carro c para manipular la inserción de productos, luego le manda un objeto Pila para que coloque en la pila la información insertada, una vez terminado este proceso, manda a llamar al metodo insertarC de la clase cola mediante el objeto cc y le manda el parámetro recien llenado c así: cc.insertarC(c);

De este modo nos aseguramos que dentro del elemento cola, se tenga una referencia hacia el elemento superior de la pila, para de este modo poder manipular la pila de productos como si estuviesen dentro de la cola.

Declaración de la pila:

Ahora sí, vamos a crear la pila con eclipse o netbeans, y sí, los de linux son exactamente iguales al netbeans y el eclipse de windows respectivamente, así que no se preocupen.

public class NodoP {
		String nom;
		double pre;
		NodoP siguiente;

		public NodoP(String nom, double pre)
			{
				this.nom=nom;
				this.pre =pre;
				this.siguiente=null;
			}
}

Los parámetros del constructor se igualan, para posteriormente pasar la información a los atributos de la clase, una vez tengamos llenos los campos.
Con esto podemos proceder a implementar los métodos  básicos de la pila, tales como insertarElemento,sacarElemento; procedemos del mismo modo.

Implementación de la pila (insertando):

Notamos que los parámetros recibidos se igualan a las variables locales nuevo, a la cual le estamos creando un espacio en memoria, estos datos que son pasados, representan el nombre y el precio del producto los cuales son llenados en otra clase.

Bien este método es bastante simple, si cabeza(referencia al primer elemento de la pila) es igual a null, significa que no existen elementos dentro de la pila, por lo cual esta instrucción solo se ejecuta una vez e inserta o mejor dicho establece, que el único elemento pasa a formar parte de la pila.

caso contrario quiere decir que cabeza ya tiene una referencia, por lo tanto pasamos a insertar el segundo elemento de la pila, para esto no existe mayor misterio, solo debemos tener cuidado se insertar adecuadamente al final.

Implementación de la pila (sacando elemento):

Como podemos apreciar este método se encarga de sacar un elemento de la pila, mostrarlo por pantalla, sumar el precio de los productos para obtener un acumulado y posteriormente desliga el elemento de la pila, de modo que no sea accesible en adelante.

Es importante recalcar que cada producto se va sacando de uno en uno, sin embargo en este método se realiza automáticamente, para evitar que el usuario procese manualmente cada producto.

Una vez tengamos la pila debidamente implementada. pasaremos a crear la cola, lo primero que debemos hacer es igual declarar una clase nodo cola.

Declaración de la cola:


Vemos que el constructor recibe como parámetro una variable de tipo Carro, la cual es la clase que contiene atributos de nombre y precio del producto, que serán insertados posteriormente dentro de una pila.

Implementación de la cola (completa):

Lo primero es tener en cuanta que utilizaremos dos punteros uno llamado primero y otro llamado último, la función de cada uno de ellos es garantizar el funcionamiento de la cola como tal, puesto que el primer elemento en ser insertado será el primero en ser procesado, de modo que la primer vez que insertemos un carro el puntero primero será asignado como primer elemento y se quedará ahí hasta que se terminen de insertar elementos, mientras que el puntero último cumple la función de ir actualizándose con cada nueva inserción.

cuando usemos el método sacaC, haremos exactamente lo que dice la teoría, despachar el primer carro que llegó a la caja registradora, para esto obviamente necesitamos sacar cada producto que este dentro del carro y es por ello que procesamos los productos con aux.car.pp.sacaP(); luego vamos sumando el total recaudado por la caja al terminar de atender a todos los carros, y finalmente desligamos cada carro de la cola.

Esto es en términos generales el ejercicio. El código completo puede ser descargado del siguiente enlace, ya está listo para correrlo desde netbeans o eclipse.

https://dl.dropboxusercontent.com/u/68911480/Pilas%20y%20colas.zip

Cualquier duda pueden comentar 🙂

Empezar a programar con C++ en linux (Arreglos)

Los vectores o arreglos son  dicho de manera vulgar, secciones o bloques apilados de manera consecutiva en las que se nos permite guardar un tipo determinado de información, visto de manera gráfica sería algo como esto:

En la imagen anterior vemos que los valores en los bloques son números enteros esto lo podríamos declarar en C++, como un vector de tipo int que es el tipo de variable que hemos visto hasta el momento.

veamos entonces la declaración de un arreglo dentro de la función main

int vector[10];

Esto crea un arreglo de tipo entero, es decir solo podremos almacenar números positivos y negativos, así como también guarda espacio para diez elementos en memoria.

Del mismo modo podemos declarar un arreglo con información ya contenida en su interior

int vector[]={0,1,2,3,4};

De modo que el tamaño del arreglo quedará sujeto al numero de elementos que le asignemos previamente, a esto se le llama inicializar un vector.
Bueno el siguiente programa que les mostraré es para insertar cinco elementos de tipo entero a un arreglo para posteriormente ser visualizado en pantalla.

#include <iostream>

using namespace std;

int main ()

{
int i, vector[5], j, interca;

cout<<" escribe 5 numeros al azar "<<endl;  /* el letrero se escribe antes para que se muestre una sola vez*/

for (i=0; i<5; i++)
/*el for es una estructura de control que permite repetir cinco veces  lo que esta entre llaves*/
cin>>vector[i];    /*lleno el vector*/

cout<<"Este es el arreglo que ingreso  ";
for (i=0; i<5; i++)
cout<<vector[i]; /*Muestra los elementos que le ingresamos al arreglo*/
cin.get();cin.get();
}

Bueno ahora a explicar un poco mejor como trabaja un for y porque es necesario su empleo en este fuente.
un for nos permite ejecutar una cantidad X de instrucciones según sean nuestras necesidades, asi por ejemplo:

for (i=0;1<3;i++)
cout<<"hola"<<endl;

El i es un subíndice, el primero nos dice donde empieza el conteo, el segundo es la condición de cuantas veces se ejecutará la instrucción esto pasará mientras el subíndice sea menor que 3 en nuestro caso particular, el tercer i nos dice en cuanto debemos aumentar la cifra del primer i para el segundo conteo, en otras palabras la segunda vez que el for se ejecuté el conteo inicial empezara en uno, puesto que el ++ significa que aumentamos una unidad.

Bueno ahora solo queda que ustedes lo compilen y modifiquen si gustan.
Comenten si lo desean…

Empezar a programar con C++ en Linux.

Esta vez es un programa sencillo, para sumar dos números enteros, vean el código


// programa que pide dos numeros para calcular su suma
//suma.cpp

#include <iostream>
using namespace std;

int main() // esta es la funcion principal

{              //siempre se deben declarar las variables del tipo correspondiente
    int a, b,suma; /* int es el tipo de las variables en este caso significa tipo entero a y b son las variables*/

    cout<<"ESCRIBA DOS NUMEROS ENTEROS PARA CALCULAR SU SUMA"<<endl;/* cout permite visualizar lo que pongamos entre comillas*/
    cin>>a>>b; /* esto nos permite asignarle a las variables a y b los valores que coloquemos en el teclado*/
    suma=a+b; /* ahora a suma le asignamos el valor de las suma de a y b va en orden de derecha a izquierda muy importante.*/

    cout<<"LA SUMA DE A + B ES "<<suma<<endl;

    return 0;

}

Esto es lo que nos debería de salir luego de compilar y ejecutar el código fuente, nada sorprendente pero de gran ayuda al menos para comprender mejor la sintaxis básica de c++



Empezar a programar con C++ en linux

No pretendo hacer un extenso tutorial, ya que mis conocimientos en c++ no pasan de principiante-intermedio, pero la idea es hacer algo que les pueda servir de ayuda, al menos para los que comienzan a programar en C++. ¿Qué herramientas necesitamos ? Bueno para empezar instalaremos los paquetes:

1. codeblocks. (aptitude install codeblocks)

2. g++. (aptitude install g++)

Una vez hecho esto, tendremos nuestro IDE codeblocks con el que podemos trabajar cómodamente escribiendo las instrucciones de nuestro programa.

Empecemos entonces:

Vamos a escribir una aplicación que nos permita calcular las tablas de multiplicar del 1 al 100.

Para facilitar de una mejora manera la lectura del programa, puedes ver el código fuente haciendo clic en el siguiente enlace.
 tablas de multiplicar

El código viene con comentarios pero si algo no les queda claro pueden escribirme, espero les sea útil para aprender.