Se nos acabaron las imágenes humorísticas
Bienvenidos a una nueva edición de “Como aprender a programar y no morir en el intento”. Soy su anfitrión, Juan Xabadu, y tal vez me recuerden de películas como: “Querida, me caí del Taxi” y “Jurassic Park vs Forrest Gump” como siempre, los acompañare en esta gran aventura en que nos hemos embarcado hace bastante tiempo, dando nuestros primeros pasos en el mundo de la programación.
Hoy veremos los primeros contenidos sobre métodos de búsqueda y ordenamiento, así como funciones y continuaremos con nuestro ejemplo del terminal de venta.
El detalle, como siempre, después del salto.
Tal como adelantábamos en el número anterior, los contenidos de hoy:
Vamos, manos a la obra:
En un escenario normal, el 99,9% de los programas que realicemos operan con una cantidad de datos mediana a alta, los cuales pueden ser o no ingresados por un usuario y son almacenados en distitnos medios, ya sea en variables, arreglos o archivos entre otras cosas.
Ahora, en un escenario más normal aún, estos datos nunca estarán necesariamente ordenados bajo algún criterio en particular, por lo que si necesitaramos acceder a ellos bajo un orden especial, sería imposible lograrlo por si solo.
Para esto es que en la programación existen los métodos de ordenamiento, los cuales son básicamente algoritmos que realizan una lectura de una serie de datos y un posterior ordenamiento de acuerdo a ciertos criterios (alfabeticamente, menor a mayor, etc).
Existen una serie de métodos de ordenamiento como el de la burbuja, quicksort, inserción, selección, etc. Cada uno de ellos se diferencia del otro tanto en su funcionamiento como en el costo (de ejecución) que significan para el programa en sí.
¿Qué método utilizar?
Si bien, como decíamos, cada método presenta ciertas ventajas por sobre otro, en ningún caso son diferencias radicales y en estricto rigor no se notan a menos que trabajemos con cantidades másivas de datos, por lo que el consejo por ahora es utilizar el método que encontremos más sencillo y/o nos acomode más. A pesar de esto hay escenarios que presentan una mejor adaptabilidad a un método en particular. Ya iremos viendo más de esto en futuras guías.
Partiendo veremos uno de los métodos más conocidos y utilizados como es el método de la burbuja, llamado de esta forma por la forma en que se realiza el ordenamiento de datos, emulando una burbuja.
¿Cómo funciona el método de la burbuja?
Este método, utilizado comunmente cuando se necesita ordenar datos dentro de un vector o una matriz, funciona mediante el uso de 4 variables:
La forma de funcionamiento es bastante simple: Nuestro vector es recorrido por una variable (la definida en el número 2) y por otra en una posición más adelante. Vamos realizando una comparación entre las 2 variables y si se cumple el criterio establecido se hace un movimiento circular: El valor más adelantado pasa a la variable auxiliar, el valor más atrasado pasa a la posición adelantada y el valor de la variable auxiliar pasa a la posición retrasada. Esto se realiza hasta que se alcanza el final del vector en cuestión.
Veamos un ejemplo de este método de ordenamiento:
Ejemplo: Ordenar un vector de tamaño 5 de menor a mayor mediante el método de la burbuja (los comentarios, como siempre, en negrita, cursiva y entre /* y */):
#include <stdio.h> #include <conio.h> #include <stdlib.h> // Incluimos las librerías int main() { int arreglo[5], aux, i, j; /* Declaramos las siguientes variables: arreglo = Un vector de 5 posiciones donde tendremos los valores. i,j = Variables para recorrer el vector. aux = Variable para guardar un valor mientras lo ordenamos */ printf ("Ingrese valores para llenar el vector:\n"); // Mostramos un mensaje e introducimos valores al vector for (i=0; i< 5; i++) scanf("%d",&arreglo[i]); /* Luego, ordenamos el vector mediante el algoritmo de burbuja: Recorremos el vector con una variable más adelantada que la otra y comparamos. Si el valor de la posición actual es mayor al de una posición más, guardamos el valor actual en la variable auxiliar, luego en la posición actual ponemos el valor de la posición siguiente y en la posición siguiente guardamos el valor de la variable auxiliar */ for (j=1; j <= 5; j++) for (i=0; i< 4; i++) if (arreglo[i] > arreglo[i+1]) { aux = arreglo[i]; arreglo[i] = arreglo[i+1]; arreglo[i+1] = aux; } printf ("\nValores ordenados exitosamente!\n"); // Mostramos el vector ordenado for (i=0; i< 5; i++) printf ("arreglo[%d] = %d\n", i, arreglo[i]); getch(); }
Como podemos ver, es un algoritmo bastante simple que cumple la función solicitada, ordenar de menor a mayor aplicando el método de la burbuja. Existen otros métodos que serán de mayor utilidad cuando trabajemos con una cantidad de datos mayor, pero por ahora con este podremos cumplir el objetivo sin problemas.
Una funcionalidad que siempre es útil al momento de hacer un programa, es la de poder buscar un dato específico del que necesitamos saber información o bien trabajar con el.
En lenguajes de programación de 3a generación, orientados al proceso, como C, existen una serie de métodos de búsqueda que nos permiten cumplir esa tarea, entre ellos podemos destacar la búsqueda secuencial, la binaria, acceso directo y el trabajo mediante índices.
¿En que se diferencian?, tal como en el caso de los métodos de ordenamiento, cada uno de estos métodos se separa de otro por la forma en la que trabajan y el costo de ejecución que implica para el programa en sí. Todas a su vez tienen una serie de ventajas y desventajas, siendo la más “costosa” de todas la búsqueda secuencial, debido a que su forma de trabajo es buscar una referencia indicada registro por registro, uno a la vez como si examináramos una serie de filas una por una hasta encontrar lo que buscamos. Sin embargo, es esta última, la más sencilla de implementar y la que menos requerimientos tiene.
Su funcionamiento se explica mediante el siguiente algoritmo:
Consideremos que tenemos un vector, el cual está lleno de códigos numéricos de productos de un supermercado y necesitamos buscar un producto en particular. Al ingresar el código a buscar y decirle al programa que lo ubique en tal vector, operaría de la siguiente manera:
Como podemos apreciar, es un funcionamiento simple y básico, pero que funciona. El gran problema radica cuando estamos operando con una cantidad masiva de datos, ya que los accesos a memoria serían demasiados y el costo de ejecución (algo que los programadores siempre deben tener en cuenta) sería alto.
Adicionalmente es bueno añadir que ese ejemplo referencia a un escenario ideal donde los códigos no están repetidos. En caso de que lo estuviesen, deberíamos avisar en cada posición que se encuentre una coincidencia.
Veamos un ejemplo de búsqueda secuencial:
Ejemplo: Llenar un vector de tamaño 5 con números y luego buscar algún valor y mostrar por pantalla la posición en la que se encuentra:
#include <stdio.h> #include <conio.h> #include <stdlib.h> // Incluimos las librerías int main() { int arreglo[5],i,valor,x; /* Declaramos las siguientes variables: arreglo = Un vector de 5 posiciones donde tendremos los valores. i = Variable para recorrer el vector. valor = Variable para guardar el valor a buscar x = Bandera que utilizamos para marcar que hayan valores. */ x=0; // Dejamos como 0 a x, lo que significa que no se han encontrado coincidencias printf ("Ingrese valores para llenar el vector:\n"); // Mostramos un mensaje e introducimos valores al vector for (i=0; i< 5; i++) scanf("%d",&arreglo[i]); // Solicitamos que se ingrese un valor a buscar printf("\nIngrese un valor a buscar: "); scanf("%d",&valor); /* Recorremos el vector y vamos comparando las posiciones con el valor a buscar, si hay una coincidencia, mostramos la posición por pantalla y marcamos la variable x con un 1 para indicar que se encontro valor */ for (i=0; i < 5; i++) if (arreglo[i] == valor) { printf("\nEl valor se encuentra en la posicion %d",i); x=1; } if(x==0) printf("\nNo se encontraron coincidencias"); getch(); }
En la Parte 6 de esta saga, veíamos en una primera instancia lo que eran las funciones cuando hablabamos de pseudo-código. Los conceptos son exactamente los mismos, así como la forma de funcionamiento y operación de la función en sí, es decir:
tipo nombre_funcion(valor 1, valor 2... valor n) { operación 1; operación 2; . . operación n; retorno de valor; }
Veamos un ejemplo para dejar todo más claro:
Ejemplo: Determinar el mayor entre 2 números mediante el uso de una función:
#include <stdio.h> #include <conio.h> #include <stdlib.h> // Incluimos las librerías int numero_mayor(int valor1, int valor2); // Declaramos inicialmente la función int main() { int num1, num2, mayor; //Declaramos las variables que utilizaremos // Pedimos que se ingresen los numeros printf("\nIngrese Numero 1: "); scanf("%d",&num1); printf("\nIngrese Numero 2: "); scanf("%d",&num2); // A mayor le asignaremos el resultado de la función mayor=numero_mayor(num1,num2); // Mostramos el resultado por pantalla printf("\nEl numero mayor es: %d",mayor); getch(); } int numero_mayor(int valor1, int valor2) // Recibimos los valores { // Comparamos cual es mayor y lo retornamos if(valor1>valor2) return valor1; else return valor2; }
Siguiendo con nuestro clásico ejemplo del terminal de ventas, si recordamos, la última vez habíamos dejado nuestro ejemplo adaptado para poder realizar más de una venta y vender en cada una de ellas más de un producto.
Bueno, el trabajo que realizaremos hoy será confeccionar un menú para que la aplicación sea más completa y la función de ventas solo sea una parte de ese menú.
Como recordaremos, al final del ejemplo anterior, teníamos el siguiente código:
#include <stdlib.h> #include <stdio.h> #include <conio.h> /* Incluimos las librerías */ int codigo, cantidad, valor, total, vuelto, pago; /* Declaramos las variables que usaremos en el proceso */ int ok=1; /* Adicionalmente declaramos una variable ok, que nos servirá de bandera para un ciclo que usaremos */ int opcion=1; /* Declaramos una variable opcion, que regulara si queremos hacer más de una venta */ int main() { while(opcion==1) { while(codigo!=4) /* Definimos un ciclo que se ejecute siempre que el usuario no presione la tecla para finalizar la venta */ { printf("\t Lista de productos\n"); /* Listamos los productos */ printf("Codigo\t Nombre\t Precio\n"); printf("1\t Silla\t 100\n"); printf("2\t Puerta\t 350\n"); printf("3\t Sillon\t 200\n"); printf("\nPara cerrar la venta, presione 4"); /* Añadimos la opción para cerrar la venta */ printf("\nIngrese el codigo del producto que desea llevar: "); /* Pedimos el código del producto */ scanf("%d",&codigo); /* Leemos el código del producto */ if(codigo==4) /* Si el código es igual a 4, significa que la venta está finalizada, así que cerramos el proceso de venta */ break; printf("\nIngrese la cantidad que desea llevar: "); /* Pedimos la cantidad */ scanf("%d",&cantidad); /* Leemos la cantidad */ if(codigo==1) /* Igualamos el código para asignar el precio */ valor=100; if(codigo==2) valor=350; if(codigo==3) valor=200; total=total+(valor*cantidad); /* A total le asignamos, el total acumulado hasta ahora, más el nuevo valor y nueva cantidad, multiplicados entre sí */ } printf("\nEl total es de: %d",total); /* Saliendo de la venta, indicamos el total */ while(ok==1) /* Declaramos un ciclo con la variable ok, para el proceso de pago y vuelto, así se ejecutará hasta que se pague la cantidad correcta */ { printf("\nIngrese el pago: "); /* Solicitamos el pago */ scanf("%d",&pago); /* Leemos el pago */ if(pago<total) /* Si el pago es inferior al total, mostramos un mensaje de error */ printf("\nEl pago no es suficiente"); else /* De lo contrario, cambiamos el valor de ok para romper el ciclo y mostramos los mensajes de vuelto */ { ok=0; vuelto=pago-total; printf("\nEl vuelto es de: %d",vuelto); } } printf("\n¿Desea hacer otra venta? (1=Si , 0=No): "); /* Preguntamos si desea hacer otra venta */ scanf("%d,",&opcion); /* Leemos la respuesta */ } printf("\nVenta finalizada"); /* Mensaje final */ getch(); /* Programa en pausa hasta pulsar una tecla */ }
Todo aquel código se refiere a lo que nombraríamos como “módulo de ventas”, que es la funcionalidad principal del programa. Para confeccionar un menú, algo muy conveniente es hacer uso de un ciclo tipo do-while y un switch, de la siguiente forma, utilizando una nueva variable llamada menu para recoger la opción elegida, nuestro programa quedaría así:
Llamado a librerías declaración de variables main do { printf("1.- Módulo de ventas\n"); printf("2.- Administrar productos\n"); printf("3.- Administrar clientes\n"); printf("4.- Cerrar sistema\n"); printf("Ingrese opción: "); scanf("%d",&menu); switch(menu) { case 1: Aquí insertaríamos nuestro código anterior del módulo de ventas break; case 2: Por ahora en blanco, pero iría el código para administrar los productos break; case 3: Por ahora en blanco, pero iría el código para administrar los clientes break; case 4: Nada break; } }while(menu!=4); Fin de función main
Con ese código, que dejaríamos al principio de nuestro programa, insertando el código anterior en el caso 1 del switch, le diríamos al menú que se ejecutase hasta que se seleccione la opción 4, que es cerrar sistema.
No es un código difícil de implementar, solo debemos fijarnos en el orden y no tendremos problemas.
Y eso sería en la edición de hoy de Como aprender a programar y no morir en el intento. En el próximo número cubriremos:
Como siempre, les recordamos que este tutorial ha sido:
Cualquier duda que puedan tener, los invitamos a dejarnos un comentario en el área habilitada a continuación.
Esperamos que este tutorial haya sido de utilidad para Uds.
Muchas gracias por leer y será hasta una próxima oportunidad.
11:28:47 pm
Excelente explicaciòn gracias por tomarse la gran pero gran molestia de explicar detalladamente como se piensa al programar; creo que esto nos va a servir a todos como seguir el camino hacia la programaciòn bien estructurada, esto sera bueno para todos muchas gracias y hasta la prixima byes
5:52:15 pm
Excelente, muy didactico
10:31:04 am
ola kisiera saber si existe publicaciones nuevas osea el 11 o si hay otra es muy interesante esto ya q empece a estudiar programacion y kisiera saber mas del tema
gracias
10:39:50 am
@melissa: Se están preparando nuevas partes de esta saga, así que atenta.
Saludos!
7:29:40 pm
Parece ser que esta guía se ha quedado en el olvido 🙁
Que lástima. Me encantaría haber continuado con mi enseñanza a este magnífico lenguaje.
7:13:30 pm
acabo de encontrar esta mina de oro y la voy a aprovechar al maximo……..aprontencen para atender mis dudas..
atte
kmferre.
6:59:42 am
Mi más sincera Enhorabuena! , me parece Brillante!, Tengo que dar unas clases a gente que no sabe programar y te voy ha citar, puesto que tu trabajo merece la pena ser Citado.
Muchas Gracias!.
7:23:57 pm
11?????????? SI o NO
12:15:44 pm
que le paso al siguiente capitulo T_T esta muy buena esta guia
8:06:28 pm
NO entendi nada =(