Código C++

  • Blog
  • Acerca
  • Autor
  • Contacto
  • Simular una Progress Bar en C++

    Una progress bar es la barrita, generalmente verde, que aparece en sistemas operativos e infinidad de programas cuando algo se está cargando. Hoy no nos vamos a meter en asuntos de cargar archivos o algo, únicamente vamos a ver el principio básico sobre el que operan estas barras.

    Nuestro programa sólo pedirá una cantidad en segundos, que será el tiempo que durará en llenarse nuestra progress bar. A la ventana donde se ejecutan nuestros programas le caben 80 caracteres de largo, así que vamos a decir que nuestra progress bar tiene una resolución de 80. El único problema es saber cuánto durará cada unidad de esas 80 para que en total se acumule el tiempo indicado.

    La función delay() o Sleep()

    Si en su IDE pueden usar la librería conio.h, entonces van a usar la función delay(). Si no, vamos a tener que agregar la librería windows.h y usar la función Sleep() (así con mayúscula).

    Ambas funciones hacen exactamente lo mismo: paran el programa durante una cierta cantidad de tiempo en milisegundos. Por ejemplo:
    cout << "Hola" << endl;
    Sleep(2000);
    cout << "Hace dos segundos te saludé!";

    Se muestra 'Hola', se pausa 2 segundos y se muestra 'Hace dos segundos te saludé!'

    Para los que usan conio.h, sería algo así:
    printf("Hola\n");
    delay(2000);
    printf("Hace dos segundos te saludé!");

    Ahora sí, para saber cuanto tiempo durará cada unidad de nuestra barra tenemos primero que convertir los segundos a milisegundos (s*1000), luego dividirlos entre la resolución de la barra (s*1000/80). Así que nuestro programa queda así:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    #include<windows.h>
    #include<iostream>
    using namespace std;
     
    int main()
    {
        int s;
        cout << "Segundos?: "; cin >> s;
        for(int i=0; i<=79; i++)
            cout << "_";
        for(int i=0; i<=79; i++)
        {
            cout << "=";
            Sleep(s*1000/80);
        }
    }

    El primer ciclo es solo por estética, para ver hasta donde va a llenar la barra. El segundo es el que imprime la barra con sus respectivas pausas.

    Pues la idea que se me ocurrió en el otro post resultó ser más sencilla de lo que me imaginé, y ahora sí la función recursiva se ve mucho mejor, ya es mucho más que un ciclo disfrazado.

    Comenté extensivamente el código, así que aquí está:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    
    #include<string.h>
    #include<iostream>
    using namespace std;
    int len, n=0;
     
    string chk4palindrosity(string thestr)
    {
        if(thestr[0] == thestr[thestr.length() - 1]) // comparar primer caracter con ultimo
        {
            n++;
            if(n == len / 2) // si el numero de veces que la comparación ha sido cierta es...
                return "Si es palindromo!"; // igual a la mitad de los caracters, es palindromo
            thestr.erase(0, 1); // borramos primer caracter
            thestr.erase(thestr.length() - 1, 1); // borramos ultimo
            return chk4palindrosity(thestr); // llamamos a la función con el string recortado
        }
        else // si una de las comparaciones no es cierta, no es palíndromo
            return "No es palindromo";
    }
     
    int main()
    {
        char inputf[50]={0}, input[50], *parte;
        cout<<"Introduce un palindromo: "; cin.getline(input, '\n');
     
        parte = strtok(input, " ");                 //
        strcat(inputf, parte);                     //
        while((parte = strtok(NULL, " ")) != NULL) //
            strcat(inputf, parte);               // quitar espacios del array
     
        string thestr(inputf); // convertir array en string para facilitar operaciones
        len = thestr.length(); // obtener longuitud del string
        if(len == 1)
            cout << "Si es palindromo!";
        else
            cout << chk4palindrosity(thestr); // llamar a la funcion e imprimir lo que retorne
        cin.get();
    }

    Lo que hace la función recursiva es comparar el primer caracter con el último, si son iguales recortarlos y llamarse; si no, no es palíndromo. Cualquier duda ya saben que los comentarios están abiertos.

    Saber si es palíndromo o no, de forma recursiva

    Hace unos días me pidieron por correo un programa que nos dijera si un string es palíndromo o no, pero usando una función recursiva. Me pareció interesante aunque raro que pidieran hacerlo de forma recursiva.

    Tal vez recuerden que ya había publicado aquí una forma de saber si un string es palíndromo o no, el cual he descubierto (ahora que hice este otro) que no es muy eficiente.

    Bueno pues el código es este:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    
    #include<string.h>
    #include<iostream>
    using namespace std;
    char cadenaf[50]={0}; int len, n=0;
     
    string chk4palindrosity(int c)
    {
        if(cadenaf[c] == cadenaf[len-1-c])
        {
            n++;
            if(n == len/2)
                return "Si es palindromo!";
            return chk4palindrosity(c+1);
        }
        else
            return "No es palindromo";
    }
     
    int main()
    {
        char cadena[50],*parte;
        cout<<"Introduce un palindromo: "; cin.getline(cadena,50,'\n');
     
        parte = strtok(cadena," ");                 //
        strcat(cadenaf,parte);                     //
        while((parte = strtok(NULL," ")) != NULL) //
            strcat(cadenaf,parte);               // quitar espacios del string
     
        len = strlen(cadenaf);
        cout << chk4palindrosity(0);
        cin.get();
    }

    La verdad es que es la función es recursiva de puro milagro. Lo que hice fue transformar el ciclo que checaba que los caracteres fueran iguales en una función en la que se aumenta una variable cada vez que se llama a sí misma.

    El código ahora es más eficiente por dos simples razones:

    1. Se detiene y da el resultado a la primera comparación de caracteres que no sean iguales. Si el primer y el último caracter no son iguales, no es palíndromo y ya no sigue analizando los demás.
    2. Sólo checa la mitad de los caracteres. Si la mitad de los caracteres corresponden a la configuración de un palíndromo, ya no hay porqué seguir analizando la otra mitad.

    Tal vez una mejor manera de hacerlo sería con una función que recibiera el string a analizar, comparar el primer y último caracter: si no, no es; si si, eliminar el primer y último caracter y volver a llamar a la función. Esto hasta que el numero de comparaciones ciertas sea igual a la mitad de la longitud inicial del string. ¿Alguien se anima a hacerlo?

    Imprimir determinados números primos

    Sobre números primos he escrito bastantes programas y me he dado cuenta de que los profesores de programación tienen cierta fijación con ellos. Pero bueno, el programa de hoy imprime la cantidad de números primos que el usuario quiera y es interesante porque es un buen ejemplo de la utilidad de los ciclos infinitos, que ya habíamos visto antes.

    Ok, el código es este:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    #include<iostream>
    using namespace std;
     
    int main()
    {
        int cnt,i=0,ii,res,nc=0,np=0;
        cout << "Introduce la cantidad de numeros: "; cin >> cnt;
        for(;;)
        {
            i++;
            for(ii=1;ii<=i;ii++)
            {
                res=i%ii;
                if(res==0)
                    nc=nc+1;
            }
            if(nc==2)
            {
                cout << i << " ";
                np++;
            }
            nc=0;
            if(np==cnt)
                break;
        }
    }

    Si tienen problemas para entender cómo obtuvimos los números primos, deberían darle una revisada a estos posts: Saber si es primo o no y Primos en un rango.

    Lo que hicimos es que todo el programa estuviera dentro de un ciclo infinito que se detendrá cuando nuestra variable que se aumenta cada vez que obtenemos un numero primo np sea igual a la variable con la cantidad deseada de números primos cnt.

    Pero recuerden que donde podemos usar un ciclo infinito, queda mucho mejor un ciclo while:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    #include<iostream>
    using namespace std;
     
    int main()
    {
        int cnt,i=0,ii,res,nc=0,np=0;
        cout << "Introduce la cantidad de numeros: "; cin >> cnt;
        while(np!=cnt)
        {
            i++;
            for(ii=1;ii<=i;ii++)
            {
                res=i%ii;
                if(res==0)
                    nc=nc+1;
            }
            if(nc==2)
            {
                cout << i << " ";
                np++;
            }
            nc=0;
        }
    }

    Únicamente ponemos la palabra while en lugar de for, copiamos la condición que ‘condicionaba’ (sí, lo se) el break y la pegamos dentro de los paréntesis del while pero de manera contraria (de == a != o de < a >).

    No se hacen proyectos finales

    Bueno pues lo dejé muy claro en el título ¿no? pero lo repito, no se hacen proyectos finales. Cuando cree este blog lo hice pensando en ayudar a todos los estudiantes de programación en c++ que necesitan algún empujón para lograr hacer sus propios programas.

    Tengo pruebas para decir que casi nunca me niego a hacer programas pequeños que me piden por correo o por comentarios, pero cuando me llegan correos pidiendo que les haga un programa que “lleve el control del inventario de un almacén registrando cada entrada y salida de producto… pidiendo tipo, cantidad, numero de control, precio… imprimiendo al final del día el reporte….. y que además haga los cálculos para…. en formato de…  y con 7 menús con… con un apartado de ayuda…. para mañana por favor” pues ni les respondo.

    La verdad es que no se vale. Durante todo el año estuvieron haciendo programas sencillos con los que era totalmente válido pedir ayuda, pero no, piden ayuda hasta el final del semestre cuando les encargan un proyecto final.

    Recuerden que yo también soy un estudiante y en estos días también estuve ocupadísimo con tareas y trabajos. Por eso no había publicado nada. ¡Pero ya estoy de vacaciones!, así que ya voy a tener un poco más de tiempo para atender mis blogs :)

    Clasificar números en C++

    Por medio de un comentario Gaby me pidió un programa que:

    “Genere 10 números aleatorios del 0 al 50 y los clasifique en 2 rangos: menores que 10 y mayores que 10 pero menores que 20.”

    A nosotros nos sirve para practicar el uso de números random, de matrices y de ciclos.

    El programa es este:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    
    #include<stdlib.h>
    #include<ctime>
    #include<iostream>
    using namespace std;
    int main()
    {
        int numrnd[10], cls1[10]={0}, cls2[10]={0}, ct1=0, ct2=0;
        srand(time(NULL));
        cout << "Los numeros: ";
        for(int i=0; i<=9; i++)
        {
            numrnd[i] = rand() % 51;
            cout << numrnd[i] << ", ";
            if(numrnd[i] < 10)
            {
                cls1[ct1] = numrnd[i];
                ct1++;
            }
            if(numrnd[i] > 10 && numrnd[i] < 20)
            {
                cls2[ct2] = numrnd[i];
                ct2++;
            }
        }
        cout << endl << "Menores que 10: ";
        for(int i=0; i<ct1; i++)
            cout << cls1[i] << ", ";
        cout << endl << "Mayores que 10 y menores que 20: ";
        for(int i=0; i<ct2; i++)
            cout << cls2[i] << ", ";
    }
    • Para dudas respecto a la generación de números random está este post: Obtener números aleatorios en C++.
    • Para dudas respecto a la declaración y uso de matrices está este otro post: ¡Ah nunca he escrito sobre matrices!, voy a tener que ponerme a ello.
    • Para dudas con respecto a los ciclos for, sí tengo un post: Ciclos for en C++.

    Tenemos 3 matrices, en la primera guardamos nuestros 10 números aleatorios, en la segunda los números que queden en la primera clasificación (menores que 10) y en la tercera los que queden en la segunda clasificación. Así que lo que hacemos es ir traspasando los valores de la primera matriz a las otras dos según su valor. Para esto tenemos que llevar en el mismo ciclo 3 cuentas diferentes, una para cada matriz.

    Las variable ct1 y ct2 se encargan de ir cambiando los índices de las matrices cls1 y cls2 respectivamente, por lo que sólo deben aumentar cuando en realidad sea necesario.

    Después lo único necesario es mostrar nuestras dos matrices. Como cada matriz puede tener un número de elementos diferentes cada vez, tenemos que hacer dos ciclos, uno para cada matriz con ct1 o ct2 como límite.

    Como última aclaración sólo digo que, tal como dice el problema, el número 10 nunca va a quedar clasificado en algún rango porque el 10 no es menor que 1o y tampoco es mayor que 10.

    Convertir segundos a horas, minutos y segundos

    Como les prometí en el post anterior, en este post vamos a hablar sobre un programa que usa los operadores compuestos de manera muy útil: convierte los segundos en horas minutos y segundos.

    El programa es este:

    #include <iostream>
    using namespace std;
     
    int main() 
    {
        int sec, hr, min;
        cout << "Introduce los segundos: "; cin >> sec;
        cout << sec << " segundos son ";
        hr = sec / (60*60);
        sec %= 60*60;
        min = sec / 60;
        sec %= 60;
        cout << hr << " horas " << min << " minutos y " << sec << " segundos" << endl;
    }

    Primero dividimos los segundos sec entre 60*60 (3600) para obtener los horas y lo guardamos en hr. Noten que la variable sec no cambia.

    Luego obtenemos el residuo de dividir sec / 60*60 (es lo que el operador % hace) y lo guardamos en la misma variable. En este paso sí modificamos la variable sec, ahora contiene los segundos iniciales menos las horas que ya obtuvimos en el paso anterior.

    Ahora dividimos nuevamente la variable sec / 60 para obtener los minutos y lo guardamos en hr. La variable sec no cambia.

    Luego obtenemos el residuo de dividir sec / 60 (es lo que el operador % hace) y lo guardamos en la misma variable. En este paso sí modificamos la variable sec, ahora contiene los segundos iniciales menos las horas menos los minutos.

    Ya sólo mostramos las tres variable y listo.

    Ahora, si somos de los que nos preocupamos por el lenguaje, veremos que a veces hay errores de ortografía como “1 minutos”. Para solucionar eso sólo necesitamos unos cuantos ifs:

    #include <iostream>
    using namespace std;
     
    int main() 
    {
        int sec, hr, min;
        cout << "Introduce los segundos: "; cin >> sec;
        cout << sec << " segundos son ";
        hr = sec / (60*60);
        sec %= 60*60;
        min = sec / 60;
        sec %= 60;
        cout << hr << " hora";
        if(hr != 1) cout << "s";
        cout << " " << min << " minuto";
        if(min != 1) cout << "s";
        cout << " y " << sec << " segundo";
        if(sec != 1) cout << "s";
    }

    Operadores compuestos en C++

    Los operadores (en cualquier lenguaje de programación) son los símbolos que permiten hacerle una operación a una o más variables. Los más conocidos son los operadores aritméticos:

    • + Suma
    • - Resta
    • * Multiplicación
    • / División
    • % Módulo (residuo de la división)

    Otros son los lógicos (&&, ||), los relacionales (<, >, !=, ==), etc. Pero en este post, como dice el título, vamos a ver los operadores compuestos en c++.

    ¿Cómo haríamos para sumarle a una variable int, por ejemplo, 3 unidades? Alguien que nunca hubiera programado escribiría algo así:
    mivar + 3;
    Sabemos que eso no es válido porque una suma retorna un valor (el resultado) y ese valor tiene que ser almacenado en una variable. En el código anterior ese valor no se almacena en ninguna variable, por lo tanto ERROR. Sabiendo esto último podemos escribir esto:
    mivar = mivar + 3;
    En la variable mivar, guardamos el contenido de esa misma variable más tres. Todo bien ¿no? eso es perfectamente válido y normal, sin embargo los operadores compuestos nos permiten hacer lo mismo con menos código:
    mivar += 3;
    Como ven está inspirado en hacer que ‘lo-primero-que-se-nos-ocurre’ sea posible.

    Así tenemos que:

    mivar = mivar + 3; es lo mismo que mivar += 3;
    mivar = mivar - 3; es lo mismo que mivar -= 3;
    mivar = mivar * 3; es lo mismo que mivar *= 3;
    mivar = mivar / 3; es lo mismo que mivar /= 3;

    Bueno, para ver un poco de la utilidad de estos operadores y haciéndole un favor a un tal Victor, vamos a ver un programa que imprima los múltiplos de un cierto número (introducido por el usuario) que haya desde 1 hasta otro cierto número (introducido por el usuario):

    #include<iostream>
    using namespace std;
    int main()
    {
        int num, lims, m=0;
        cout << "Numero?: "; cin >> num;
        cout << "Limite superior?: "; cin >> lims;
        while(lims >= (m+=num))
        {
            cout << m << ", ";
        }
    }

    Primero pedimos el número del cual queremos obtener múltiplos (num), luego el límite superior (lims). m obtendrá el valor de los múltiplos y lo tenemos que igualar a 0 al inicio.

    Luego tenemos un ciclo while. En español dice: “Me mantendré ejecutando mientras el lims sea mayor o igual a m más num“. Dentro del ciclo mostramos la variable m.

    Si, por ejemplo, num = 3, entonces la instrucción n+=num se desarrolla así:
    m = 0;
    m+=num; -----> m= m + num; -----> m = 0 + 3; -----> m = 3;
    m+=num; -----> m= m + num; -----> m = 3 + 3; -----> m = 6;
    m+=num; -----> m= m + num; -----> m = 6 + 3; -----> m = 9;
    etc, etc.

    Aquí podría poner un otro programa aún más útil para usar los operadores compuestos, pero mejor lo dejo para el siguiente post. Ah y si tú eres Victor, entonces tal vez te interese este post: Cómo contar el número de veces que sucede algo.

    Páginas: Anterior 1 2 3 4 5 6 7 8 9 Siguiente