Discussione:
Numeri random senza ripetizione
(troppo vecchio per rispondere)
Capitan Catarro
2005-09-02 13:32:59 UTC
Permalink
Ciao a tutti, io volevo fare un piccolo programmino DOS in C++ per
generare numeri da 1 a 25 random senza ripetizione. Ho pensato perciò di
inserire tutti i numeri estratti in un array, ma ora non riesco a
impedire che vengano estratti di nuovo ... qualcuno può aiutarmi?
Incollo il codice che ho fatto per ora:

for (i=0;i<27;i++)
{
srand(time(0));
numero = 1+rand()%26;

estratti[i]=numero;

cout<<"NUMERO ESTRATTO: "<<numero<<endl;
}

Grazie!
AUGH!
Bruno Ripa
2005-09-02 13:53:38 UTC
Permalink
Di fatto hai bisogno di una permutazione dell'insieme di partenza.

Algoritmo della tombola ( su 10 numeri per brevita' ):

Metti in un array A da 1 a 10 gli elementi che vuoi utilizzare ( ad
esempio le cifre da 1 a 9 ), quindi:

A[0] = 0;
A[1] = 1;
.
.
A[9] = 9;

per i = 0 ... 9

estrai un numero a casa tra 0 e 9, ad esempio esce 3.

Prendi l'elemento in posizione 3 e lo sposti in posizione 9.

Al passo successivo estrai un numero a caso tra 0 e 8, ad esempio 2.

Prendi l'elemento in posizione 2 e lo sposti in posizione 8.

Cosi' via.

Permuti un insieme di 'n' elementi in 'n' passi.

------------------------

Codice [ supponiamo che A[] sia gia' settato con gli elementi che ti
serve gestire ] :

nelem <- numero degli elementi

for( i = 0; i < nelem; i++ )
{
x = rand() % ( nelem - i );
tmp = a[x]
a[x] = a[nelem - i]
a[nelem - i] = tmp
}

Controlla gli indici che avro' fatto sicuramente casino con i vari +/- 1 :)

Ciao
Post by Capitan Catarro
Ciao a tutti, io volevo fare un piccolo programmino DOS in C++ per
generare numeri da 1 a 25 random senza ripetizione. Ho pensato perciò di
inserire tutti i numeri estratti in un array, ma ora non riesco a
impedire che vengano estratti di nuovo ... qualcuno può aiutarmi?
for (i=0;i<27;i++)
{
srand(time(0));
numero = 1+rand()%26;
estratti[i]=numero;
cout<<"NUMERO ESTRATTO: "<<numero<<endl;
}
Grazie!
AUGH!
Fred Mammola e il Tempio di Sdenk Settemani Urrins
2005-09-02 14:00:55 UTC
Permalink
Post by Capitan Catarro
Ciao a tutti, io volevo fare un piccolo programmino DOS in C++ per
generare numeri da 1 a 25 random senza ripetizione. Ho pensato perciò di
inserire tutti i numeri estratti in un array, ma ora non riesco a
impedire che vengano estratti di nuovo ... qualcuno può aiutarmi?
for (i=0;i<27;i++)
{
srand(time(0));
numero = 1+rand()%26;
estratti[i]=numero;
cout<<"NUMERO ESTRATTO: "<<numero<<endl;
}
Grazie!
AUGH!
#include <algorithm>
#include <vector>

int
main()
{
std::vector<int> numeri(25);
std::iota(numeri.begin(), numeri.end(), 1);
std::random_shuffle(numeri.begin(), numeri.end());

std::cout << "#1 estratto: " << numeri.at(0) << std::endl;
std::cout << "#2 estratto: " << numeri.at(1) << std::endl;
// cosi via...
}
--
MSN: sirpsycho_78 -at- hotmail dot com
James Kanze
2005-09-04 09:20:05 UTC
Permalink
Post by Fred Mammola e il Tempio di Sdenk Settemani Urrins
Post by Capitan Catarro
Ciao a tutti, io volevo fare un piccolo programmino DOS in
C++ per generare numeri da 1 a 25 random senza ripetizione.
Ho pensato perciò di inserire tutti i numeri estratti in un
array, ma ora non riesco a impedire che vengano estratti di
nuovo ... qualcuno può aiutarmi? Incollo il codice che ho
for (i=0;i<27;i++)
{
srand(time(0));
numero = 1+rand()%26;
estratti[i]=numero;
cout<<"NUMERO ESTRATTO: "<<numero<<endl;
}
#include <algorithm>
#include <vector>
int
main()
{
std::vector<int> numeri(25);
std::iota(numeri.begin(), numeri.end(), 1);
Scusa, ma cos'è std::iota? Questa funzione non si trova nella
norma (ne C++, ne C). Al posto, farèi:

std::vector< int > numeri(
boost::counting_iterator<int>( 1 ),
boost::counting_iterator<int>( 26 ) );
Post by Fred Mammola e il Tempio di Sdenk Settemani Urrins
std::random_shuffle(numeri.begin(), numeri.end());
std::cout << "#1 estratto: " << numeri.at(0) << std::endl;
std::cout << "#2 estratto: " << numeri.at(1) << std::endl;
// cosi via...
}
Sarebbe probabilemente utile anche di chiamare srand UNA volta,
primo di chiamare random_shuffle. Per un'applicazione "seriosa",
fornirèi anche una mia funzione di generazione aleatoria a
random_shuffle; quella presente per default è spessamente
cativa.

Ma se no, è infatti la soluzione buona.
--
James Kanze mailto: ***@free.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Fred Mammola e il Tempio di Sdenk Settemani Urrins
2005-09-05 06:14:37 UTC
Permalink
Post by James Kanze
Post by Fred Mammola e il Tempio di Sdenk Settemani Urrins
Post by Capitan Catarro
Ciao a tutti, io volevo fare un piccolo programmino DOS in
C++ per generare numeri da 1 a 25 random senza ripetizione.
Ho pensato perciò di inserire tutti i numeri estratti in un
array, ma ora non riesco a impedire che vengano estratti di
nuovo ... qualcuno può aiutarmi? Incollo il codice che ho
for (i=0;i<27;i++)
{
srand(time(0));
numero = 1+rand()%26;
estratti[i]=numero;
cout<<"NUMERO ESTRATTO: "<<numero<<endl;
}
#include <algorithm>
#include <vector>
int
main()
{
std::vector<int> numeri(25);
std::iota(numeri.begin(), numeri.end(), 1);
Scusa, ma cos'è std::iota? Questa funzione non si trova nella
hai ragione, mea culpa: é un'estensione SGI allo standard (se usi
STLPort dovrebbe essere presente).
Post by James Kanze
std::vector< int > numeri(
boost::counting_iterator<int>( 1 ),
boost::counting_iterator<int>( 26 ) );
grazie dei suggerimenti!
--
MSN: sirpsycho_78 -at- hotmail dot com
ZeD
2005-09-02 14:20:59 UTC
Permalink
Sono qui per te, Capitan Catarro!
Post by Capitan Catarro
Ciao a tutti, io volevo fare un piccolo programmino DOS in C++ per
generare numeri da 1 a 25 random senza ripetizione.
Ci sono parecchi errori, sia di concetto che ti sintassi
Post by Capitan Catarro
for (i=0;i<27;i++)
se vuoi 25 numeri, perche' vai da 0 a 26?
Post by Capitan Catarro
srand(time(0));
non serve re-inizializzare il seme dentro al ciclo
Post by Capitan Catarro
numero = 1+rand()%26;
estratti[i]=numero;
cout<<"NUMERO ESTRATTO: "<<numero<<endl;
da nessuna parte controlli che un certo numero non sia gia' stato estratto


eccoti una traccia, credo sia abbastanza comprensibile:


#include <iostream>

int main() {
bool usciti[25]={false};
int estratti=1, numero;
srand(time(0));
while (estratti<=25) {
numero=rand()%25;
if (!usciti[numero]) {
usciti[numero]=true;
std::cout<<"Estrazione n:"<<estratti
<<" numero estratto:"<<numero+1<<std::endl;
estratti++;
}
}
return 0;
}
--
la dove la goccia di rugiada svanisce
sognarti e sognare
fremente d'inverno
un bosco di neve
Continua a leggere su narkive:
Loading...