In questa lezione impareremo a generare dei numeri casuali senza ripetizioni in C. Abbiamo già studiato come è possibile caricare un array con numeri random, ovvero con dei numeri a caso tra un intervallo di valori, potete consultare il tutorial al link: array random in C.
Numeri casuali senza ripetizioni in C
Sviluppiamo un algoritmo di esempio:
Supponiamo di voler inserire in un vettore 10 numeri casuali da 1 a 30 ma senza ripetizioni.
Procedura
Di seguito ecco i passaggi per realizzare l’algoritmo che genera numeri casuali senza ripetizioni in C:
- Inizializzazione del Generatore di Numeri Casuali: Per garantire che ogni esecuzione del programma produca numeri casuali diversi, inizializziamo il generatore di numeri casuali sull’ora attuale dell’elaboratore utilizzando
srand(time(0))
. - Generazione dei Numeri Casuali: Utilizziamo la funzione
rand() % N + 1
per generare numeri casuali compresi tra 1 e N (nel nostro caso, 30). I numeri generati vengono inseriti nell’array. - Controllo delle Ripetizioni: Per evitare ripetizioni, eseguiamo un controllo all’interno di un ciclo
for
interno. Se un numero generato è già presente nell’array, decrementiamo l’indice e usciamo dal ciclo interno.
Ecco dunque il codice completo:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 10
#define MAX_RANDOM 30
int main() {
int a[N];
int i, j;
// Inizializza il generatore di numeri casuali sull'ora attuale
srand(time(0));
for (i = 0; i < N; i++) {
a[i] = rand() % MAX_RANDOM + 1; // Genera un numero casuale tra 1 e N
// Controllo delle ripetizioni
for (j = 0; j < i; j++) {
if (a[i] == a[j]) {
i--; // Decrementa l'indice se il numero è già presente
break;
}
}
}
// Visualizza i numeri casuali generati
printf("Numeri casuali generati senza ripetizioni:\n");
for (i = 0; i < N; i++) {
printf("%d\n", a[i]);
}
return 0;
}
Numeri casuali senza ripetizioni in C – Soluzione con il while
Possiamo migliorare ulteriormente le prestazioni utilizzando un approccio più efficiente che controlla direttamente la lunghezza dell’array invece di utilizzare un contatore separato. In questo modo, eviteremo di eseguire cicli di controllo aggiuntivi. Ecco come potremmo farlo:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 10
#define MAX_RANDOM 30
int main() {
int a[N];
int generated[N] = {0}; // Array per tenere traccia dei numeri già generati
int i = 0;
// Inizializza il generatore di numeri casuali sull'ora attuale
srand(time(0));
while (i < N) {
int num = rand() % MAX_RANDOM + 1; // Genera un numero casuale tra 1 e N
// Verifica se il numero è già stato generato
int j = 0;
int found = 0;
while (j < i && !found) {
if (a[j] == num || generated[num - 1] == 1) {
found = 1; // Imposta il flag se il numero è già presente
}
j++;
}
// Se il numero non è stato generato in precedenza, lo aggiunge all'array
if (!found) {
a[i++] = num; // Aggiunge il numero all'array a
generated[num - 1] = 1; // Imposta il flag di generazione per il numero
}
}
// Visualizza i numeri casuali generati
printf("Numeri casuali generati senza ripetizioni:\n");
for (i = 0; i < N; i++) {
printf("%d\n", a[i]);
}
return 0;
}
Numeri casuali senza ripetizioni in C – Soluzione con l’uso di un vettore di appoggio
Possiamo usare anche un vettore di appoggio (flag) per tenere traccia dei numeri già generati.
Ecco di seguito un possibile approccio:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 10
#define MIN_RANDOM 1
#define MAX_RANDOM 30
int main() {
int a[N];
int flag[MAX_RANDOM - MIN_RANDOM + 1] = {0}; // Vettore di flag per tenere traccia dei numeri già generati
int i, num;
srand(time(0));
for (i = 0; i < N; i++) {
do {
num = rand() % (MAX_RANDOM - MIN_RANDOM + 1) + MIN_RANDOM; // Genera un numero casuale tra MIN_RANDOM e MAX_RANDOM
} while (flag[num - MIN_RANDOM]); // Ripete finché il numero è già stato generato
a[i] = num;
flag[num - MIN_RANDOM] = 1; // Imposta il flag per il numero generato
}
printf("Numeri casuali generati:\n");
for (i = 0; i < N; i++) {
printf("%d\t", a[i]);
}
printf("\n");
return 0;
}
Conclusioni
In questa lezione abbiamo esplorato alcuni metodi per generare numeri casuali senza ripetizioni in C. Utilizzando degli approcci differenti basati sul ciclo for
e while
. In questo modo siamo riusciti a ottenere un algoritmo efficiente che ci consente di generare un array di numeri casuali unici.
Inoltre abbiamo anche aggiunto un’altra soluzione che utilizza un array aggiuntivo per tracciare i numeri già generati e una serie di controlli durante il processo di generazione. Anche questo approccio ci permette di garantire l’unicità dei numeri generati e di ottenere risultati affidabili.
Utilizzando questi metodi, siamo in grado di generare numeri casuali senza ripetizioni in modo efficiente e affidabile. Questa tecnica può essere utile in una varietà di scenari di programmazione in cui è necessario generare dati casuali unici, come nel caso di giochi, simulazioni o algoritmi di ottimizzazione. Spero che questa lezione sia stata utile e che possiate applicare questo approccio nei vostri progetti in C.
Alcuni link utili
Allocazione dinamica della memoria con malloc
Realizzare un menù di scelta in C
Somma elementi diagonale principale di una matrice