Tag Archives: rand

Aprender inglés, ¿¡en C++!?

Me contó SetRoot a través de un comentario que se le ocurrió hacer un programa en C++ que nos ayudará a aprender palabras en inglés, en sus propias palabras:
Se me ocurrio hacer un programa para aprender ingles y creo que los tiros tambien van por ahi corrígeme:
1 llenar 1000 palabras
2 agruparlas por alguna relacion como emociones articulos y otros(para esto quisiera usar una matriz para acceder a ella mas facil aunque 2 matrices tambien creo q me van :s con punteros y eso ,s)
3 ejecucion: con un par de cases hacer un menu que me permita lanzar 20 palabras al azar(con sran o ran creo + time) con su significado
y despues que me permita hacer un tipo de examen o test con esas mismas palabras desordenadas que cada acierto valga algo para ganar puntos y asi involucrar a los amigos y familiares

Me gustó la idea de hacer un pequeño ‘bosquejo’ de su idea porque precisamente se necesita usar el código de mi último post: Números aleatorios sin repetir en C++. Así que mi algoritmo es algo así:

  1. Crear una matriz tipo string de N filas y 2 columnas, la primera columna son las palabras en inglés; la segunda, en español.
  2. Pedir el número de palabras que el usuario quiera memorizar.
  3. Obtener ese número de palabras aleatoriamente y mostrarlas.
  4. Borrar las palabras y empezar a preguntar el significado de cada una.
  5. Comparar la respuesta del usuario con la respuesta correcta.
  6. Calcular su calificación y mostrarla.

El código es este:

#include
#include
#include
using namespace std;

int nofw;
#define N 8 // numero de pares de palabras en la matriz

bool checkrep(int n, int num[])
{
    for(int i=0; i<nofw; i++)
        if(n == num[i])
            return true;
    return false;
}

int main()
{
    srand(time(NULL));
    string ans, words[N][2] = {{"hi", "hola"}, {"house", "casa"}, {"water", "agua"},
      {"roof", "techo"}, {"chair", "silla"}, {"loudspeaker", "bocina"},
      {"screen", "pantalla"}, {"money", "dinero"}};
    int n, correct=0, wrong=0;
    cout <> nofw;
    // obtener 'nofw' palabras aleatoriamente de nuestra matriz
    int num[nofw];
    for(int i=0; i<nofw; i++)
    {
        do
            n = rand() % N;
        while(checkrep(n, num));
        num[i] = n;
        cout << words[n][0] < " << words[n][1] << endl;
    }
    cin.get(); cin.get();
    system("cls");
    // preguntar el significado de cada palabra
    for(int i=0; i<nofw; i++)
    {
        cout << words[num[i]][0] <> ans;
        if(ans == words[num[i]][1])
        {
            correct++;
            cout <> Bien :)nn";
        }
        else
        {
            wrong++;
            cout <> Mal :(nn";
        }
    }
    cout << "Tuviste un " << (float)correct / (float)nofw * 100 <<
                "% de respuestas correctas.";
    cin.get(); cin.get();
}

Como dije antes, es sólo un bosquejo, pero tal vez sea el punto de partida para un buen proyecto. Para optimizarlo creo que se deberían agregar algunas cosas:

  • Obtener los pares de palabras desde una base de datos
  • Ordenarlas por categorías
  • Que no importe si la respuesta está en mayúsculas o minúsculas
  • Mejorar la interacción con el usuario
Advertisements

Números aleatorios sin repetir en C++

Ya hemos visto cómo obtener número aleatorios en c++, pero tarde o temprano surge la necesidad de generar números aleatorios pero sin que se repitan. Podría ser útil para varias cosas como por ejemplo, ordenar de manera aleatoria elementos de una lista, formas grupos aleatorios, barajear cartas, etc. Así que en algoritmo quedaría algo así:

  1. Crear una matriz y dejarla vacía.
  2. Obtener un número aleatorio.
  3. Checar si ese número existe en la matriz. Si si, regresar al paso 2. Si no, guardar el numero en la matriz.

Así que el programa es este:

#include
#include
#include
using namespace std;

bool checkrep(int n, int num[])
{
    for(int i=0; i<10; i++)
        if(n == num[i])
            return true;
    return false;
}

int main()
{
    srand(time(NULL));
    int n, num[10];
    for(int i=0; i<10; i++)
    {
        do
            n = 1 + rand() % 10;
        while(checkrep(n, num));
        num[i] = n;
        cout << num[i] << "  ";
    }
}

Primero que nada, <cstdlib> es la forma correcta de incluir la librería <stdlib.h> en c++, igual con <ctime>.

Como ven, usamos una función bool (que retorna falso o verdadero) para checar si el número aleatorio ya existe en nuestra matriz. Si cualquiera de los números es igual a nuestro número aleatorio n, la función retorna true, por lo que el ciclo do-while desde el cual llamamos la función tendrá que repetirse una vez más y hasta que la función retorne false.

Cuando se logra salir del ciclo do-while, guardamos nuestra n en el lugar de la matriz que corresponda, lo mostramos en pantalla y continuámos con la siguiente posición de la matriz.

Otra cosa. Para decirnos si un número está repetido en la matriz, la función checkrep() necesita obviamente dos cosas, el número aleatorio y la matriz. Así que le enviámos como parámetros nuestra matriz y nuestro número aleatorio.

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:

#include
#include
#include
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 && 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.

Generar un string aleatorio en C++

No sé, es algo que se me ocurrió y que es muy fácil de hacer. Lo único que tenemos que hacer es ver a un string no como una frase, sino como un conjunto de caracteres; y además ver a los caracteres no como letras, sino números del código ASCII.

Teniendo esto claro, es muy fácil generar un números aleatorios (que representas letras) para llenar cada elemento del arreglo que es nuestro string. Veamos:

#include
#include
#include
using namespace std;

int main()
{
    char strrnd[10];
    srand(time(NULL));
    for(int i=0; i <= 9; i++)
        strrnd[i] = 33 + rand() % (126 - 33);
    cout << strrnd;
    cin.get();
}
  1. Primero declaramos un string de nombre strrnd.
  2. Luego inicializamos nuestro random.
  3. Con un ciclo recorremos cada elemento del string.
  4. Y cada elemento lo llenamos con un número aleatorio entre 33 y 126, que en el código ASCII representan todos las símbolos letras y números normales.
  5. Y listo, ya hemos creado un string aleatorio en c++.

Si tienen duda con los números aleatorios pueden checar este post: Obtener número aleatorios en c++. Aquí pueden ver el código ASCII.

Si quieren que muestre, por ejemplo, solo letras minúsculas, tendrían que modificar la fórmula del random para que generara números entre el 97 y 122.

Obtener numeros aleatorios en C++ (rand, srand)

Es algo muy frecuente, cuando ya dominas todo eso de pedir y almacenar datos, ahora tu profesor te pedirá que tus programas generen números aleatorios para automatizar el proceso de llenar arreglos y todo eso.

Así que lo primero que tenemos que hacer es incluir la librería:
#include<stdlib.h>
Luego inicializar los números aleatorios incluyendo esto:
srand(time(NULL));
*Actualización: No se porqué con algunos IDE’s tira error con la función time. Solo hay que utilizar además la librería time.h:
#include<time.h>
Luego guardar el número aleatorio en alguna parte:
num=rand();

Eso es básicamente. Para ajustar el rango de número aleatorios podemos hacer varias cosas.

Número aleatorios entre 0 y 50:
num=rand()%51;

Número aleatorios entre 1 y 100:
num=1+rand()%(101-1);

Número aleatorios entre 250 y 420:
num=250+rand()%(421-250);

De forma general es:
variable = limite_inferior + rand() % (limite_superior +1 - limite_inferior) ;

Así que un programa que muestre 10 números aleatorios entre 1 y 10 quedaría así:

#include
#include
using namespace std;

int main()
{
    int num,c;
    srand(time(NULL));
    for(c=1;c<=10;c++)
    {
        num=1+rand()%(11-1);
        cout<<num<<" ";
    }
    cin.get();
}

Histograma con números aleatorios y asteriscos

Bueno, tal vez el título quedó muy poco descriptivo, pero la idea es pedir un número de personas, luego se le pediría a cada persona su peso pero nosotros solo vamos a generar un número aleatorio en determinado rango. Luego se clasificaría a esas personas en rangos de peso y al final mostrar una tabla que muestre la frecuencia de cada rango con asteriscos, así:

51-60 ***
61-70 **
71-80 ***
80-91 *
91-mas *****

El código en C++ sería así:

#include
#include
using namespace std;

int main()
{
    int n,c,c2,peso[500],cat[5]={0},lim;
    // n -> numero de personas
    // c y c2 para ciclos
    // peso[500] arreglo para guardar el peso de las personas
    // cat[5] arreglo para guardar el número de personas en cada categoria de peso
    srand(time(NULL)); // Inicializa los números aleatorios
    cout<>n;
    for(c=0;c50 && peso[c]60 && peso[c]70 && peso[c]80 && peso[c]90)
            cat[4]++;
    }
    cout<<"n";
    for(c=0;c<=4;c++)
    {
        switch(c)
        {
            // segun cada caso imprime algo diferente
            case 0:
                cout<<"51-60t";
            break;
            case 1:
                cout<<"61-70t";
            break;
            case 2:
                cout<<"71-80t";
            break;
            case 3:
                cout<<"81-90t";
            break;
            case 4:
                cout<<"90-  t";
            break;
        }
        lim=cat[c]; // no podemos usar un arreglo como limite del ciclo (la verdad
                   // no se porque), entonces lo pasamos a una variable normal
        for(c2=1;c2<=lim;c2++)
                cout<<"*";
        cout<<"nn";
    }
    cin.get();cin.get(); // detiene la ejecución al final (es como getch();)
}

A propósito, este programa fue una petición especial de un usuario.