Mostrando entradas con la etiqueta while. Mostrar todas las entradas
Mostrando entradas con la etiqueta while. Mostrar todas las entradas

martes, 29 de diciembre de 2020

Cambio de base

Vimos en la explicación del operador MOD un ejemplo de hacer un cambio de base de un número decimal a un binario. En esta oportunidad lo que haremos es generalizar este ejemplo y hacer un programa en C++ que haga el cambio de base del decimal a uno cualquiera que introduzcamos por pantalla.

Un ejemplo de ejecución sería el siguiente:



Lo que vemos en este ejercicio es el uso de:

  • El operador MOD (%)
  • El iterador do-while
  • El iterador for con índice creciente y decreciente

A continuación os dejo el código y podríamos pensar algunas variantes como la representación en base hexadecimal teniendo en cuenta las letras.


int main(int argc, char** argv) {

int base10;

int baseN;

char res[50]; //array que almacena los residuos según los va calculando

int nRes = 0;

char res2[50]; //array que almacena los residuos con la lectura inversa (resultado final)

printf("Ingresa un numero en base decimal:");

scanf("%d", &base10);

printf("\nIngresa la base a la que quieres cambiar:");

scanf("%d", &baseN);

int q = base10;

int r = 0;

//calcula residuos hasta que el cociente es 0

do{

r = q % baseN; //calcula residuo

q = q / baseN; //recalcula la nueva "q" para la siguiente iteración

res[nRes] = r; //concatena el residuo al resultado

nRes++; //número de cifras del resultado

}while(q > 0);


//invierte el resultado (la lectura de los residuos es invertida)

for(int i = (nRes - 1); i >= 0; i--) res2[nRes - i - 1] = res[i];

//imprime  resultado en pantalla

printf("\n%d en base %d es: ", base10, baseN);

for(int i = 0; i < nRes; i++) printf("%i", res2[i]);

return 0;

}

sábado, 17 de septiembre de 2016

Mostrar un menú de sistema

Después de unas largas "vacaciones" vuelvo recargada de energía para empezar un nuevo curso, estos últimos meses he podido empezar mi web de docente que aún está en construcción, la voy avanzando poco a poco y ya os daré el enlace cuando esté terminada.

Mientras tanto quiero compartir que hoy empecé con la primera alumna en este curso 2016-2017 y vimos un problema que se repite mucho, sobretodo en la facultad de Gestión Aeronáutica de la UAB (que últimamente son con los que más trabajo), se trata de mostrar un menú de sistema con distintas opciones:

1. Empezar reserva
2. Modificar reserva
3. Facturar reserva
4. Cancelar reserva
5. Salir

El menú se debe mostrar, realizar las acciones que el usuario seleccione y al terminar de ejecutar cada acción volver a mostrar el menú hasta que el usuario marque salir.

El objetivo de este ejercicio es:

- Reconocer que es necesario el uso de un bloque de instrucciones iterativas (while/for/do-while) para mostrar el menú hasta que el usuario decida salir
- Reconocer que es más práctico utilizar el bloque de instrucciones switch en lugar de if's anidados

A continuación muestro el código comentado en C++

int main(int argc, char** argv) {
//define una variable que guarde la opción seleccionada por el usuario
int opcion =0;
//escogemos do-while para asegurar que el menú se muestre al menos la primera vez
do 
{
                //imprimimos las opciones disponibles del menú
printf (" 1. Hacer reserva\n 2.Modificar reserva\n 3.Facturar reserva\n 4.Cancelar reserva\n 5.Salir\n");

                //leer de teclado la opción seleccionada por el usuario
printf ("Seleccione una opcion\n");
scanf ("%d",&opcion);

                //utiliza el bloque switch para decidir que acción realiza según la opción seleccionada
switch (opcion) 
{
case 1: printf ("Haciendo reserva\n");
break;
case 2: printf ("Modificando reserva\n");
break;
case 3: printf ("Facturando reserva\n");
break;
case 4: printf ("Cancelar reserva\n");
break;
case 5: printf ("Salir\n");
break;

default: printf ("Opcion incorrecta\n");
break;
}
}
while (opcion !=5);//en caso que seleccione la opción 5 termina de ejecutar la iteración

return 0;
}

A continuación muestro unas capturas de pantalla de la ejecución:









domingo, 20 de julio de 2014

Algo de matrices

Una de las dificultades más comunes son los vectores, sobretodo comprender la diferencia entre el indice de un vector (posición) y el valor contenido en el índice del vector (datos).

Para complicarlo aún más viene el tema de las matrices, que no son más que vectores pero en dos dimensiones, esto es que ahora el índice está formado por dos posiciones.

Sobre teoría de matrices se ha escrito mucho, lo que pretendo en este post es simplemente mostrar como acceder a una matriz y determinar si es una matriz identidad o no (¿Qués es una matriz identidad?). Para este fin utilizaremos el recorrido secuencial de una matriz fila a fila y para cada elemento de la fila veremos si tiene el valor correcto que le corresponde a la matriz identidad (1 en la diagonal y 0 en el resto de campos):

int esIdentidad = 1; //variable que indica si la matriz es identidad o no
int x, y = 0; //indice de filas y columnas
int N=10;//dimensión de la matriz

//se asumen que la matriz es de Identidad hasta que se muestre que tenga un valor incorrecto
while(esidentidad)
{
  //recorre todos los elementos de la fila hasta que encuentre algún error o termine la fila
  for(int y=0; y<N && esIdentidad; y++)
  {
    //la diagonal debe tener el valor 1, en caso contrario no puede ser una matriz Identidad
    if(x==y && Matriz[x][y] !=1) esidentidad = 0;
    //los que no están en la diagonal deben ser 0, en caso contrario no puede ser una matriz identidad
    if(x!=y && Matriz[x][y] !=0) esidentidad = 0;
  }
  x++;//cada iteración del while se corresponde con cada fila de la matriz  
}

//resultado de la evaluación
if(esIdentidad) print("La matriz es identidad");
else print("La matriz no es identidad");


Vemos que el el indice de la  matriz está compuesto por dos posiciones: x e y.
Vemos que el valor en una posición determinada de la matriz se accede a través de las posiciones: Matriz[x][y].
Vemos que cuando encuentra un valor que no se corresponde con la matriz identidad cambia la variable esIdentidad para salir inmediatamente de los bucles for y while, puesto que al primer valor incorrecto no hace falta seguir recorriendo la matriz, ya sabemos que no es de Identidad.
Vemos que para recorrer una matriz hace falta 2 bucles anidados, en este caso el while recorre las filas de la matriz y el for recorre las columnas para cada fila.



viernes, 17 de mayo de 2013

Búsqueda del valor máximo

Uno de los problemas académicos más comunes es el de la búsqueda del valor máximo o mínimo dentro de una lista. Una aplicación que podríamos darle a este problema sería por ejemplo con fines estadísticos, calcular para una muestra de datos: el máximo, el mínimo y el valor medio.

Antes de plantear el problema vamos a intentar "pensar en cámara lenta" y preguntarnos qué haría nuestra cabeza si tuviésemos que encontrar el valor máximo de una muestra de datos. Suponemos la siguiente muestra de datos:

2, 5, 10, 1, 7

A simple vista diríamos que el máximo es 10, pero ¿Cómo es que lo hemos determinado? si lo vemos en cámara lenta nos daríamos cuenta que:

1. Comparamos el 2 y el 5, como el 5 es mayor, nos quedamos con el 5 y descartamos el 2.
2. Comparamos el 5 con el 10, como el 10 es mayor, nos quedamos con el 10 y descartamos el 5.
3. Comparamos el 10 con el 1, como el 10 es mayor, nos quedamos con el 10 y descartamos el 1.
4. Comparamos el 10 con el 7, como el 10 es mayor, nos quedamos con el 10 y descartamos el 7.

Finalmente el último con el que nos quedamos fue el 10, por tanto, es el 10 el valor máximo.

Si analizamos cada uno de los pasos, vemos que en cada uno de ellos se compara un elemento de la lista con el valor con el que nos hemos quedado en el paso anterior. Si llevamos esto a lenguaje de programación  se puede plantear como un recorrido por todos los elementos de una lista en la que cada iteración realza una comparación entre el valor actual con el máximo de la iteración anterior, por tanto sabemos que debemos tener una estructura así:

//creamos la muestra de datos
int listaNumeros [5]; 
listaNumeros[0] = 2;
listaNumeros[1] = 5;
listaNumeros[2] = 10;
listaNumeros[3] = 1;
listaNumeros[4] = 7;

//tenemos un recorrido de la muestra
for(int i=0; i<5;i++)
{
  //comparamos el valor actual con el resultado de la iteración anterior
  if (listaNumeros[i] > valor_maximo)
  {
    //esta linea representa el "nos quedamos con" de cada paso
    valor_maximo = listaNumeros[i]; 
  }
}

Hasta aquí tenemos la estructura básica del algoritmo, ahora le hacemos algunos ajustes, teniendo en cuenta que la variable valor_maximo no la hemos inicializado.
Si la inicializaramos con 0, nos corremos el riesgo de que para otra muestra tengamos valores negativos y en ese caso el máximo siempre sería 0, lo mejor es tomar como máximo algún valor de la muestra, por ejemplo el primero.

//inicializamos el valor máximo con el primer elemento de la muestra
int valor_maximo = listaNumeros[0];

//tenemos un recorrido de la muestra
for(int i=0; i<5;i++)
{
  //comparamos el valor actual con el resultado de la iteración anterior
  if (listaNumeros[i] > valor_maximo)
  {
    //esta linea representa el "nos quedamos con" de cada paso
    valor_maximo = listaNumeros[i]; 
  }
}

Ahora que nos aseguramos que el valor_maximo de la muestra sea uno de los elementos de la muestra, vemos que la primera iteración comparará listaNumeros[0] y valor_maximo y que siempre serán iguales en la primera iteración, por tanto el código que está dentro del if núnca se ejecutará en la primera iteración, así que podemos aplicar una optimización haciendo que empiece la iteración a partir del segundo elemento, de la siguiente forma.


//inicializamos el valor máximo con el primer elemento de la muestra
int valor_maximo = listaNumeros[0];

//el recorrido se inicia en el segundo elemento
for(int i=1; i<5;i++)
{
  //comparamos el valor actual con el resultado de la iteración anterior
  if (listaNumeros[i] > valor_maximo)
  {
    //esta linea representa el "nos quedamos con" de cada paso
    valor_maximo = listaNumeros[i]; 
  }
}

Finalmente, aprovecharemos el mismo recorrido para calcular el máximo, el mínimo y la media:

//creamos la muestra de datos
int listaNumeros [5]; 
listaNumeros[0] = 2;
listaNumeros[1] = 5;
listaNumeros[2] = 10;
listaNumeros[3] = 1;
listaNumeros[4] = 7;

int valor_maximo = listaNumeros[0];
int valor_minimo = listaNumeros[0];
int media = listaNumeros[0];

for(int i=1; i<5;i++)
{
  //Búsqueda del máximo
  if (listaNumeros[i] > valor_maximo)
  {
    valor_maximo = listaNumeros[i];
  }

  
  //Búsqueda del mínimo
  if (listaNumeros[i] < valor_minimo)
  {
    valor_minimo = listaNumeros[i] ;
  }

  //cálculo de media
  media +=  listaNumeros[i] ;

}

//al terminar el recorrido la variable media contiene la suma de todos los elementos
//dividimos entre el número de elementos para calcular la media
media = media/5;

//En este punto tenemos calculado los tres valores estadísticos de la muestra, los imprimimos en pantalla
printf("valor_maximo: ", valor_maximo);
printf("valor_minimo: ", valor_minimo);
printf("media: ", media);



domingo, 24 de marzo de 2013

Lo que no debemos olvidar en una iteración

Este post intenta dar las 3 claves principales que no debemos olvidar nunca al realizar iteraciones:

1. Definir e inicializar la variable que itera: Esta variable será la que determine en qué iteración nos encontramos y servirá para terminar la iteración.

2. La condición tope para que termine la iteración: Esta condición evalúa la variable itera y determina si debe continuar iterando o no.

3. La variación de la variable que itera: Esta variación se debe realizar en cada iteración para asegurar que la variable en algún momento cumplirá la condición tope.

Un ejemplo sencillo: Sumar los 10 primeros números enteros positivos:

//variable que acumula la suma
int Suma = 0;
//variable que itera: se inicializa con el primer entero positivo
int i = 1;

//la condición es que la variable iteradora no supere 10, así asegura que se suman los 10 primeros números
while (i <= 10)
{
    suma += i;
    //variación de la variable i, se incrementa en 1
    i++;
}

//cuando salimos del while la variable i vale 11 y la variable suma contiene la suma desde 1 hasta 10

Ahora haremos un ejemplo un poco más complejo, haremos una función que calcule la integral entre 0 y 1 de la función f(x) = x^2

El método que utilizaremos será discretizar la función en incrementos de h = 0.001

float inicio = 0;
float final = 1;
float h = 0.001; //variaciones 
float integral = 0; //en esta variable se guarda el valor calculado de la integral
int it = 0; //esta variable guarda el número de iteraciones que se realicen

float i = inicio; //variable que itera y que se evalúa en la condición tope
//la condición que marca el tope es que no sobrepase el final = 1
while (i <= final)
{
    integral += i * i ; //la evaluación de la función f(x)=x^2 en el punto i es f(i) = i^2 = i*i
    i += h; //incremento de la variable iteradora
    it++;
}
//cuando termina el bucle la variable i contiene un número > a final
//la variable integral contiene la suma de la evaluación de la función en todos los puntos i
//la variable it contiene el número total de iteraciones que se realizaron, que es igual al número de veces que //se evaluó f(i)

//para terminar de calcular la integral se divide entre el número de iteraciones
integral = integral / it;