Hoy vamos a ver un ejercicio de programación en lenguaje C, también conocido como ANSI C. Se trata de generar números aleatorios, agregarlos a una lista (arreglo) y luego agruparlos para obtener la frecuencia con la que se repiten.
El ejercicio dice así:
Realizar un programa que genere de manera aleatoria 100 números en el intervalo del conjunto del 1 al 20, y después genera una lista con la frecuencia de cada número. Los números generados de manera aleatoria se deben de visualizar; la frecuencia de números se debe visualizar.
Veamos cómo resolverlo usando una pila, arreglos y algunas funciones.
Lo primero que debemos hacer es declarar un arreglo de 100 elementos, y llenarlo con números aleatorios. También declaramos una pila dinámica que nos servirá para registrar la frecuencia de los números.
Al llenar el arreglo también agregamos los elementos a la pila (de hecho el arreglo no haría falta, porque la pila tendrá tanto la frecuencia como el número).
En caso de que el número no exista en la pila, lo registramos con una frecuencia de 1. Y si el número ya existe, entonces aumentamos su frecuencia.
Declaramos un struct
que será un nodo de la pila. Tiene el número, la frecuencia con la que aparece y un apuntador al siguiente nodo.
Obviamente esto se podría optimizar si usáramos un diccionario en lugar de una pila, pero a mi parecer es más fácil gestionarlo con una pila (a nivel de programación, no a nivel de rendimiento).
struct nodo {
int numero;
int frecuencia;
struct nodo *siguiente;
};
struct nodo *superior = NULL;
Cuando se inserta un nuevo número por primera vez, se inserta un elemento en la pila.
void agregarPorPrimeraVez(int numero) {
struct nodo *nuevoNodo = malloc(sizeof(struct nodo));
nuevoNodo->numero = numero;
nuevoNodo->frecuencia = 1;
nuevoNodo->siguiente = superior;
superior = nuevoNodo;
}
Como puedes ver en la línea 4, la frecuencia por defecto es 1.
Hasta ahora tenemos nuestra pila y agregamos los números por primera vez, pero debemos manejar el caso de que el número ya exista justamente para aumentar su frecuencia en este ejercicio de programación en C.
Por lo tanto definimos una función que regresa un apuntador a la memoria en donde se encuentra el número, o NULL
en caso de que no se encuentre. Queda así:
struct nodo *obtenerApuntadorANumero(int numeroBuscado) {
struct nodo *temporal = superior;
while (temporal != NULL) {
if (temporal->numero == numeroBuscado) {
return temporal;
}
temporal = temporal->siguiente;
}
return NULL;
}
Recorremos toda la pila y si encontramos el número, regresamos el apuntador a ese nodo. En caso contrario regresamos NULL
.
Ahora cada que vayamos a agregar un número hacemos la comprobación: si ya existe, obtenemos el apuntador y aumentamos la frecuencia. Si no, lo agregamos por primera vez:
void registrarNumero(int numero) {
struct nodo *apuntador = obtenerApuntadorANumero(numero);
if (apuntador == NULL) {
agregarPorPrimeraVez(numero);
} else {
apuntador->frecuencia++;
}
}
Ahora para imprimir los números aleatorios y la frecuencia con la que aparecen, simplemente recorremos la pila y vamos imprimiendo. Para ello usamos el ciclo while
en el lenguaje C, así como printf
.
void imprimirFrecuencias() {
struct nodo *temporal = superior;
while (temporal != NULL) {
printf("Número %d frecuencia %d\n", temporal->numero, temporal->frecuencia);
temporal = temporal->siguiente;
}
}
Anteriormente expliqué todo el código para contar la frecuencia con la que aparecen los números, pero no hemos visto el llenado del arreglo con números aleatorios ni las funciones para generar los números.
Todo el código queda como se ve a continuación dentro de main
:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define MAXIMA_CANTIDAD 100
/*
____ _____ _ _ _
| _ \ | __ \ (_) | | |
| |_) |_ _ | |__) |_ _ _ __ _____| |__ _ _| |_ ___
| _ <| | | | | ___/ _` | '__|_ / | '_ \| | | | __/ _ \
| |_) | |_| | | | | (_| | | / /| | |_) | |_| | || __/
|____/ \__, | |_| \__,_|_| /___|_|_.__/ \__, |\__\___|
__/ | __/ |
|___/ |___/
____________________________________
/ Si necesitas ayuda, contáctame en \
\ https://parzibyte.me /
------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Creado por Parzibyte (https://parzibyte.me). Este encabezado debe mantenerse intacto,
excepto si este es un proyecto de un estudiante.
*/
int aleatorio_en_rango(int minimo, int maximo) {
return minimo + rand() / (RAND_MAX / (maximo - minimo + 1) + 1);
}
struct nodo {
int numero;
int frecuencia;
struct nodo *siguiente;
};
struct nodo *superior = NULL;
struct nodo *obtenerApuntadorANumero(int numeroBuscado) {
struct nodo *temporal = superior;
while (temporal != NULL) {
if (temporal->numero == numeroBuscado) {
return temporal;
}
temporal = temporal->siguiente;
}
return NULL;
}
void agregarPorPrimeraVez(int numero) {
struct nodo *nuevoNodo = malloc(sizeof(struct nodo));
nuevoNodo->numero = numero;
nuevoNodo->frecuencia = 1;
nuevoNodo->siguiente = superior;
superior = nuevoNodo;
}
void registrarNumero(int numero) {
struct nodo *apuntador = obtenerApuntadorANumero(numero);
if (apuntador == NULL) {
agregarPorPrimeraVez(numero);
} else {
apuntador->frecuencia++;
}
}
void imprimirFrecuencias() {
struct nodo *temporal = superior;
while (temporal != NULL) {
printf("Número %d frecuencia %d\n", temporal->numero, temporal->frecuencia);
temporal = temporal->siguiente;
}
}
int main() {
srand(getpid());
int minimo = 1;
int maximo = 20;
int i;
int numeros[MAXIMA_CANTIDAD];
for (i = 0; i < MAXIMA_CANTIDAD; i++) {
int numeroAleatorio = aleatorio_en_rango(minimo, maximo);
numeros[i] = numeroAleatorio;
registrarNumero(numeroAleatorio);
}
printf("Imprimiendo números\n");
for (i = 0; i < MAXIMA_CANTIDAD; i++) {
printf("%d,", numeros[i]);
}
printf("\n");
printf("Imprimiendo frecuencias\n");
imprimirFrecuencias();
return 0;
}
Hay varias cosas en el método main
, por ejemplo el llenado de la lista y la impresión de todas las cosas. Recuerda que en este caso hicimos conteo de números en C, anteriormente ya había explicado cómo contar la frecuencia de palabras.
También puedes leer más sobre lenguaje C en mi blog.
Igualmente dejo un vídeo en YouTube explicando todo este ejercicio
Hoy te voy a presentar un creador de credenciales que acabo de programar y que…
Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…
En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…
En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…
Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…
En este artículo te voy a enseñar cómo usar un "top level await" esperando a…
Esta web usa cookies.