Matrices y ordenamiento
Hola que tal. En esta entrada les dejo un programa para mostrar varias capacidadades de C tales como creacion de menus, manejo de arreglos unidimensionales e impresion y llenado de datos en matrices
Este programa es relativamente grande, por lo que es una buena experiencia para irse acostumbrando a ver codigos cada vez de mayor tamaño
Hello, for non spanish speakers you can use the translate button to change the article to your current language. To see the code at the end of the article go back to spanish because it scarmbles.
Este programa contiene 3 opciones las cuales se muestran a continuacion
Tomando en cuenta que una aplicacion comercial regular por lo general consta de 3000 a 5000 lineas aproximadamente podemos usar este codigo como una forma de entrenamiento a ver un programa como una serie de elementos que tienen una relacion entre si el cual puede expandirse o probarse por partes en el proceso de depuracion.
Para cambiar el color de letra y el fondo se hace por medio de la instrcuccion system. Esta funcion es parte de la biblioteca #include<Windows.h> . En los comentarios al inicio del programa.
system("cls");
system("color F9"); //letra azul y fondo blanco (mi favorito jaja)
Sobre la imagen de bellas Artes
Como gusto le agregue al programa una imagen de Bellas Artes para decorar el menu. La imagen hecha con printf(); esta ubicada en una funcion la cual puede ser llamada a distintas partes del programa segun el gusto del programador.
Como consejo para hacer sus propias figuras les aconsejo hacerla desde Bloc de Notas o WordPad es mas comodo y mezckar varios caracteres para darle un poco de vida a la imagen
Opciones del programa
Este programa muestra las siguientes opciones
1.-Ecuacion cuadratica
Resuelve una ecuacion cuadratica y genera sus resultados para los 3 posibles casos incluyendo raices complejas
2.-Vector con histograma
Esta opcion cuenta con una serie de funciones para realizar un ordenamiento tipo Burbuja
en forma ascendente o descendente
3.-Matriz 2x3
Imprime una matriz de un tamaño determinado por el usuario
4.-Salir
Sale del programa por medio de la instruccion exit
Imagen de las funciones del programa
El programa fue probado y hecho en Visual Studio 2012.
El programa tiene dos grupos de funciones. El primero de ellos es un grupo de menu para cada uno de las opciones del programa y el segundo son las funciones necesarias para el ordenamiento tipo burbuja.
La funcion de ordenamiento tipo Burbuja funciona por medio de apuntadores y la variable entera orden como seleccion de opcion ya sea ascendente o descendente
Recuerda que el apuntador debe estar inicializado previamente de su uso a la variable a la cual esta apuntando
La sintaxis para moverse con las variables tipo apuntador de un arreglo es
*(vectorPtr + i)
Se necesitan los parentesis para asegurar la precedencia de operadores. El operador apuntador (operador unario) tiene una precedencia mayor que +. Consulta tu tabla de precendencia de operadores.
Sobre la ordenación tipo burbuja
Burbuja consiste en realizar varias pasadas a traves del arreglo en la cual se realizan comparacion de pares sucesivos de elementos. los elementos se intercambian dependiendo del tipo de ordenamiento ya sea este ascendente o descendente
La funcion swap es la encargada de hacer el intercambio
void swap(int *element1Ptr, int *element2Ptr)
{
int temp;
temp = *element1Ptr;
*element1Ptr = *element2Ptr;
*element2Ptr = temp;
}//fin de swap
La variable temp guarda temporalmente el valor para el intercambio. Esta ordenacion tiene la desventaja de ser lento para arreglos de mayor tamaño, por lo que se sugiere usar otros algoritmos segun los requisitos de tu proyecto.
Aqui les dejo una serie de capturas en pantalla del funcionamiento de las distintas opciones del programa. Déjenme sus comentarios y hasta la proxima.
/*Programa de vectores, Matrices y Raiz cuadrada Mayo-2015
-----------------------------
Blog de Rincon Informatico
Autor: Juan Lopez
----------------------------
NOTA DE USO
Este Programa fue escrito con propositos de aprendizaje y academicos Aplicaciones comerciales o de otro uso
requieren una mayor robustez del codigo, pruebas, asi como su posible escritura a lenguajes de programacion
mas apropiados para calculos numericos como Fortran o C# o Java para aplicaciones.
Aprovecha lo que aprendas de este programa y dejame tus comentarios de este blog espero te sea de utilidad
DESCRIPCION
Este programa tiene opciones para calculos matematicos y de
manejo de vectores y matrices
-------------------------------------------------------
Este programa muestra las siguientes opciones
1.-Ecuacion cuadratica
Resuelve una ecuacion cuadratica y genera sus resultados para los 3 posibles casos incluyendo raices complejas
2.-Vector con histograma
Esta opcion cuenta con una serie de funciones para realizar un ordenamiento tipo Burbuja
en forma ascendente o descendente
3.-Matriz 2x3
Imprime una matriz de un tamaño determinado por el usuario
4.-Salir
Sale del programa por medio de la instruccion exit
--------------------------------------------------------------
CODIGO DE COLORES PARA EL COMANDO SYSTEM
0 = Negro
8 = Gray
1 = Azul
9 = Light Blue
2 = Verde
A = Light Green
3 = Aqua
B = Light Aqua
4 = Rojo
C = Light Red
5 = Pupura
D = Light Purple
6 = Amarillo
E = Light Yellow
7 = Blanco
F = Bright White
*/
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include<conio.h>
#include<math.h>
#include<ctype.h> //manejo de caracteres
#define MARGEN 30
#define MAX 100
#define CADENA 30
#define SIZE 100 //TAMAÑO MAXIMO QUE PUEDE ALCANZAR EL VECTOR
#define MAX_VEC 15 //VALORES MINIMO Y MAXIMO DEL RANGO DE ENTRADA PERMITIDO
#define MIN_VEC -15
//tamaño maximo de la matriz
#define MAX_RENG 100
#define MAX_COL 100
/* Definicion de estructuras y enumeraciones */
enum {OPCION_1 = 1, OPCION_2, OPCION_3, OPCION_4 };
/* Definicion de funciones*/
void menu_1(void);
void menu_2(void);
void menu_3(void);
void menu_sal(void);
void bellasArtes(void);
//FUNCIONES PARA FUNCIONAR EL ALGORITMO DE ORDENACION TIPO BURBUJA EN ORDEN ASCENDENTE Y DESCENDENTE
void burbuja(int *, const int, int (*)(int, int));
void swap(int *, int *);
int ascending(const int, const int);
int descending(const int, const int);
int main()
{
int opcion; //avriables de control de menu
char salida;
system("cls");
//system("color F9"); //letra azul y fondo blanco
system("color 0F");
// system("color 0E");
//system("color 09");
char nombreMenu[CADENA], c; //agregar un nombre al menu
int i = 0;
//ingresar tu nombre al inicio del programa
printf(" Ingresa tu nombre: ");
while( ( c= getchar() ) != '\n')
nombreMenu[i++] = c;
nombreMenu[i] = '\0'; //insertar NULL al final de la cadena
do{//comienzo de la ejecucion del programa
system("cls");
system("color 0F");
printf("\t--Programas de Matematicas basicas Matrices y vectores --\n\n");
bellasArtes(); //imagen de bellas Artes
printf("Hola: ");
puts(nombreMenu);
printf("\n\t[ 1 ]- Opcion 1. Raiz cuadrada\n");
printf("\t[ 2 ]- Opcion 2. Vector con histograma\n");
printf("\t[ 3 ]- Opcion 3. Matriz 2x3\n");
printf("\t[ 4 ]- Opcion 4 SALIDA.\n\n");
printf("*Selecciona la opcion que quieres accesar: ");
scanf("%d", &opcion);
switch(opcion){
case OPCION_1:
menu_1();
break;
case OPCION_2:
menu_2();
break;
case OPCION_3:
menu_3();
break;
case OPCION_4:
menu_sal();
break;
}//fin de switch
//reinicilializacion de variables tipo contador
printf("\n\n¿Desea una nueva opcion(S/N)?: ");
salida = getch();
salida = tolower(salida);
}while(salida == 's' || salida == 'S');
system("cls");
printf("\t--Plantilla de menus basica 1.0--\n\n");
printf("\n\nFin de la ejecucion.");
return 0;
} //fin de main
/*OPCIONES DE MENU ESTAS OPCIONES PUEDEN LLEGAR A LLAMAR A OTRAS FUNCIONES PARA REALIZAR SUS TAREAS
*/
void menu_1(void)
{
system("color 0E");
printf("\n\n\t\aOPCION 1 Raiz cuadratica: Ingresa Enter para continuar");
//valores de la ecuacion cuadratica y radical de la formula general
int a, b, c, i;
double discrim, discrim_comp; //valor del discriminante
int caso = 0, respuesta = 0; //bandera de casos y tipo de respuesta
double real, imagi_1, imagi_2;
//resultados de la ecuacion cuadratica
double valor_1, valor_2;
printf("\n\nInstrucciones.\n\nEl programa resuelve una ecuacion de la forma ax2 + bx + c = 0: \n");
printf("Ingresa los valores de la ecuacion cuadratica: \n\n");
//lectura de datos
do{ //verifica que los datos sean validos este valor no puede ser cero de lo contrario ademas de no ser vaiido produce division / cero
printf("\a*.-Ingresa el valor de a: ");
scanf("%d", &a);
if(a == 0)
printf("\nAVISO: EL VALOR INGRESADO NO ES VALIDO: INTENTA DE NUEVO\nEste valor da el termino cuadratico y no puede omitirse ni valer cero.\n");
}while(a == 0);
printf("\a*.-Ingresa el valor de b: ");
scanf("%d", &b);
printf("\a*.-Ingresa el valor de c: ");
scanf("%d", &c);
//seleccion del tipo de respuesta
if(b != 0 && c != 0) //ax2 + bx + c = 0
respuesta = 1;
else if (b == 0 && c != 0) //ax2 + c = 0
respuesta = 2;
else if(b != 0 && c == 0) //ax2 + b = 0
respuesta = 3;
discrim = (pow((double)b, 2) - 4.0*(double)a*(double)c); //seleccion del tipo de respuesta EVALUACION DEL DISCRIMINANTE
// printf("%f ", discrim);
if(discrim > 0 ) //dos soluciones reales y diferentes
{
// printf("\nDos soluciones reales.");
caso = 1;
valor_1 = ( -(double)b + sqrt(discrim)) / (2.0 * (double)a);
valor_2 = ( -(double)b - sqrt(discrim)) / (2.0 * (double)a);
}
else if(discrim == 0 ) //una solucion real Una raiz de multiplicidad 2 DISCRIMINANTE CERO
{
// printf("\nUna solucion real.");
caso = 2;
valor_1 = ( - (double)b ) / (2 * (double)a);
}
else if(discrim < 0 ) //solucion en numeros complejos, no hay raiz real
{
caso = 3;
real = -(double)b / (2 * (double)a);
discrim_comp = discrim * -1.0; //valor positivo del discriminante para poder sacar la raiz
// printf("%f %f", discrim, discrim_comp);
imagi_1 = sqrt( discrim_comp ) / (2.0 * (double)a);
imagi_2 = sqrt( discrim_comp ) / (2.0 * (double)a);
}
printf("\n\n");
for( i = 0; i <= MARGEN; i++)
printf("*");
printf("\n\n-Reporte de resultados.-\n\n");
for( i = 0; i <= MARGEN; i++)
printf("*");
if(respuesta == 1)
{
if(a == 1) //presentacion
printf("\n\nLa ecuacion x2 + %dx + %d = 0 tiene como solucion: \n\n", b, c);
else
printf("\n\nLa ecuacion %dx2 + %dx + %d = 0 tiene como solucion: \n\n", a, b, c);
}
else if(respuesta == 2)
{
if(a == 1)
printf("\n\nLa ecuacion x2 + %d = 0 tiene como solucion: \n\n", c);
else
printf("\n\nLa ecuacion %dx2 + %d = 0 tiene como solucion: \n\n", a, c);
}
else if(respuesta == 3)
{
if(a == 1)
printf("\n\nLa ecuacion x2 + %dx = 0 tiene como solucion: \n\n", b);
else
printf("\n\nLa ecuacion %dx2 + %dx = 0 tiene como solucion: \n\n", a, b);
}
// printf("\n%f \n %f \n %f", discrim, imagi_1, imagi_2);
//printf("\n\nLa ecuacion %dx2 + %dx + %d = 0 tiene como solucion: \n\n", a, b, c);
switch(caso)
{
case 1: printf("Caso I: Dos raices reales y distintas.\n");
for( i = 0; i <= MARGEN; i++)
printf("-");
printf("\n\tDiscriminante: %3.2f\n\n", discrim);
printf("\tRaices\n");
printf("\tx_1 = %4.2f\n", valor_1);
printf("\tX_2 = %4.2f\n", valor_2);
break;
case 2: printf("Caso II: Una Raiz real. \n");
for( i = 0; i <= MARGEN; i++)
printf("-");
printf("\n\tDiscriminante: %3.2f\n\n", discrim);
printf("\tRaiz\n");
printf("\tx_1 = %4.2f\n", valor_1);
break;
case 3: printf("Caso III: Dos raices complejas conjugadas. \n");
for( i = 0; i <= MARGEN; i++)
printf("-");
printf("\n\tDiscriminante: %3.2f\n\n", discrim);
printf("\tRaices\n");
printf("\tX_1 = %3.2f ", real); //primer resultado
printf("+");
printf(" %2.2f i \n", imagi_1);
printf("\tX_2 = %3.2f ", real); //segundo resultado
printf("-");
printf(" %2.2f i \n", imagi_2);
break;
} //fin de seleccion de casos
//reseteo de variables de control (Banderas)
caso = 0;
respuesta = 0;
getchar();
}//fin de menu_1
void menu_2(void)
{
system("color 0E");
printf("\n\n\t\aOPCION 2 Vector con histograma: Ingresa Enter para continuar");
int vector[SIZE] = {0}; //declaracion e inicializacion del vector
int *vectorPtr = vector;
int orden; //selecciona el tipo de ordenamiento
int valor;
int *valorPtr = &valor;
printf("\tPrograma de un vector con apuntadores.-\n\n");
do{ //ingreso del tamaño del vector
printf(" Ingresa el tamaño del vector(2-100): ");
scanf("%d", &valor);
if(valor <=2 && valor >= 100)
printf("RANGO INVALIDO: Intenta de nuevo.\n");
}while(valor <=2 && valor >= 100);
printf(" Ingresa los %d valores\n\n", valor);
for(int i = 0; i < valor; i++)
{
do{
printf("%d.-Ingresa tu valor: ", i+ 1);
scanf("%d", &*(vectorPtr + i) );
if( (*(vectorPtr + i) <= MIN_VEC) && ( *(vectorPtr + i) >= MAX_VEC) )
printf("FUERA DE RANGO(%d|%d): Intente de nuevo \n", MIN_VEC, MAX_VEC);
}while( (*(vectorPtr + i) <= MIN_VEC) && ( *(vectorPtr + i) >= MAX_VEC) );
}//fin de ingreso de valores
for(int i = 1; i <= MARGEN; i++)
printf("-");
printf("\n\n* Reporte de valores *\n");
for(int i = 1; i <= MARGEN; i++)
printf("-");
printf("\n");
printf("\n\nTamaño total del arreglo = %d bytes\nElementos en vector libres = %d \n", sizeof(vector), sizeof(vector)/sizeof(float) - valor);
printf("\nImpresion de valores\n(*)Valores positivos (-)Valores negativos\nVector Tamaño: %d\n Datos en el orden original\n\n", *valorPtr); //impresion de resultados Uso del apuntador *valorPtr
getchar();
printf("%4s %3s\n\n", "Valor", "Histograma");
for(int i = 0; i < valor; i++)
{
printf("vector[ %2d ] = %2d ", i, *(vectorPtr +i));
if(*(vectorPtr + i) > 0){ //impresion de asteriscos
for(int j = 0; j < *(vectorPtr + i); j++) //valores positivos
printf("%c", '*');
}else if(*(vectorPtr + i) < 0){
for(int j = 0; j < abs(*(vectorPtr + i)); j++) //valores negativos
printf("%c", '-');
}
printf("\n");
}
getchar();
printf("Selecciona el tipo de orden para tus datos\n");
printf(".-Ingresa 1 para orden ascendente\n");
printf(".-Ingresa 2 para orden descendente\n");
printf("Elige el tipo de ordenacion: ");
scanf("%d", &orden);
printf("\n");
if(orden == 1){
burbuja(vectorPtr, valor, ascending);
printf("Datos en orden ascendente\n\n");
}else{
burbuja(vectorPtr, valor, descending);
printf("Datos en orden ascendente\n\n");
}
getchar();
//impresion de valores en el orden seleccionado
printf("%4s %3s\n\n", "Valor", "Histograma");
for(int i = 0; i < valor; i++)
{
printf("vector[ %2d ] = %2d ", i, *(vectorPtr +i));
if(*(vectorPtr + i) > 0){ //impresion de asteriscos
for(int j = 0; j < *(vectorPtr + i); j++)
printf("%c", '*');
}else if(*(vectorPtr + i) < 0){
for(int j = 0; j < abs(*(vectorPtr + i)); j++)
printf("%c", '-');
}
printf("\n");
}
getchar();//fin de impresion
//getchar();
}
void menu_3(void)
{
system("color 0E");
printf("\n\n\t\aOPCION 3 Matriz 2X3:\n\n");
int renglon, columna; //variables de renglon y columna
int matriz[MAX_RENG ][MAX_COL ] = {0}; //declaracion e inicializacion de la matriz
int matrices; //selecciona las dimensiones de la matriz
char opc; //seleccion de opcion
do{
printf("\n\t[ 1 ]- Opcion 1. Matriz 2X3 \n");
printf(" \t[ 2 ]- Opcion 2. Seleccionar dimension\n");
scanf("%d", &matrices);
switch(matrices){
case 1: printf("Matriz 2X3 seleccionada\n");
renglon = 2;
columna = 3;
//lectura de valores de la matriz
printf("\n\n\tIngreso de datos de la matriz %d X %d\n\tTeclea %d valores para llenar la matriz.\n\n", renglon, columna, renglon * columna);
for(int i = 0; i <= renglon -1; i++){
for(int j = 0; j <= columna -1; j++){
printf("vector[%d][%d] = ", i, j);
scanf("%d", &matriz[i][j]);
if(renglon % 10 == 0) //nueva linea
printf("\n");
}
}
getchar();
printf("\n\n\tImpresion de la matriz\n");
printf("\n");
for(int i = 0; i < renglon; i++){ //impresion de la matriz
printf("|");
for(int j = 0; j < columna; j++){
printf(" %d ", matriz[i][j] );
}
printf("|");
printf("\n"); //nueva linea
}
getchar();
break;
case 2: printf("Seleccionar dimension\n\n");
do{ //lectura de valores de renglon y columna
printf("Ingresa el valor RENGLON (2-100): ");
scanf("%d", &renglon);
if(renglon <= 2 && renglon >= 100 )
printf("Rango invalido, intenta de nuevo\n");
}while(renglon <=2 && renglon >= 100);
do{
printf("Ingresa el valor COLUMNA (2-100): ");
scanf("%d", &columna);
if(columna <= 2 && columna >= 100 )
printf("Rango invalido, intenta de nuevo\n");
}while(columna <=2 && columna >= 100);
//lectura de valores de la matriz
printf("\n\n\tIngreso de datos de la matriz %d X %d\n\tTeclea %d valores para llenar la matriz.\n\n", renglon, columna, renglon * columna);
for(int i = 0; i <= renglon -1; i++){
for(int j = 0; j <= columna -1; j++){
printf("vector[%d][%d] = ", i, j);
scanf("%d", &matriz[i][j]);
if(renglon % 10 == 0) //nueva linea
printf("\n");
}
}
getchar();
printf("\n\n\tImpresion de la matriz\n");
printf("\n");
for(int i = 0; i < renglon; i++){ //impresion de la matriz
printf("|");
for(int j = 0; j < columna; j++){
printf(" %d ", matriz[i][j] );
}
printf("|");
printf("\n"); //nueva linea
}
getchar();
break;
default: printf("Opcion invalida, intenta de nuevo");
break;
}//fin de seleccion de matrices
printf("Desea otra seleccion?");
opc = getch();
opc = tolower(opc);
//matriz[MAX_RENG ][MAX_COL ] = {0}; //reinicializacion de la matriz
}while(opc == 's' && opc == 'S');
printf("\n\nFin de la ejecucion de matrices. ENTER para continuar..");
//getchar();
}
//funcion de salida del menu
void menu_sal(void)
{
char salir;
printf("\n\n\t\aOPCION 4 SELECCIONADA: ");
printf("\n\nConfirmar para salir(S/N): ");
salir = getch();
salir = tolower(salir);
if(salir == 's' || salir == 'S'){
getch();
printf("\n\n\tHasta luego Vuelve pronto (ENTER para salir)...");
exit(EXIT_SUCCESS); //esta funcion obliga a que se termine el programa Al ser llamado exit mediante EXIT_SUCCESS el valor definido de la puesta en marcha para una terminacion exitosa se regresa al entorno llamador
}else{//regresar al menu
printf("\n*.-Ingresa Enter para regresar al programa.");
getchar();
}
}//fin de la salida
//Despliega una imagen del Palacio de Bellas Artes
void bellasArtes(void)
{
printf("\t ** \n");
printf("\t ** \n");
printf("\t **** \n");
printf("\t **| | ** \n");
printf("\t **|| || |||** \n");
printf("\t ** ------------- ** \n");
printf("\t * *| ||||||||| |* * \n");
printf("\t *********** *********** \n");
printf("\t || || | || | || || || \n");
printf("\t ------ ------------ ------- \n");
printf("\t || || ------------- || || \n");
printf("\t ** || * * []| | | | | |[] * * || ** \n");
printf("\t **** || * * []| | | | | |[] * * || **** \n");
printf("\t * * || * * []| | | | | |[] * * || * * \n");
printf("\t -------------------------------------------------- \n");
printf("\t -------------------------------------------------- \n\n\n");
}//fin de funcion bellas Artes
//implementacion de algoritmo de ordenacion tipo burbuja
void burbuja(int *arreglo, const int size, int (*compare)(int, int))
{
int pass, j;
void swap(int *, int *);
for(pass = 1; pass <= size -1; pass++){
for(j = 0; j <= size -2; j++){
// if(arreglo[j] > arreglo[j + 1])
// swap(&arreglo[j], &arreglo[j + 1]);
if((*compare)(arreglo[j], arreglo[j + 1]) )
swap(&arreglo[j], &arreglo[j+ 1]);
}
}
}//fin de ordenacion tipo burbuja
void swap(int *element1Ptr, int *element2Ptr)
{
int temp;
temp = *element1Ptr;
*element1Ptr = *element2Ptr;
*element2Ptr = temp;
}//fin de swap
int ascending(const int a, const int b)
{
return b < a;
}
int descending(const int a, const int b)
{
return b > a;
}
//FIN DE PROGRAMA