PDA

Visualizza la versione completa : Generare numeri casuali non ripetuti c++


davix10
16-05-2014, 23:26
Salve a tutti, dovrei generare dei numeri casuali non ripetuti ma non riesco a capire come fare. Questo è ciò che ho provato a fare ma funziona solo in parte perchè non riesco a capire come eseguire un nuovo controllo del numero estratto.



for(i=0;i < 7;i++)
{
numeri_casuali[carte]=rand()%51+1;
for(j=0;j < i;j++)
{
if(numeri_casuali[carte]==numeri_casuali[j])
{
numeri_casuali[carte]=rand()%51+1;


}
}
carte=carte+1;


Grazie in anticipo!

Scara95
17-05-2014, 07:24
Se n'è già parlato diverse volte..

davix10
17-05-2014, 12:33
Sì ma vorrei anche capire il motivo del perchè non va, non solo copiare un pezzo di programma e stop..

M.A.W. 1968
17-05-2014, 12:59
Si tratta decisamente di una FAQ. Tra le centinaia di thread al proposito, segnalerei questo (http://forum.ubuntu-it.org/viewtopic.php?f=33&t=570017) che, oltre ad essere uno dei più recenti, coniuga caratteristiche di chiarezza e approfondimento teorico degli algoritmi impiegati alla presentazione del banale codice C funzionante, facilmente adattabile a C++.
Ulteriori considerazioni analoghe sono contenute in questo thread (http://forum.ubuntu-it.org/viewtopic.php?f=33&t=574995#p4539369).
Inoltre, una ricerca nel presente forum ti fornirà numerosi altri risultati simili.

davix10
19-05-2014, 18:57
Io ho provato a fare in questo modo:


a=0;
while(a<numero)
{
srand(time(0));
for(i=a*7;i < (a*7)+7;i++)
if(!i) numeri_casuali[i]=rand()%51+1;
else do
{


d=0;
numeri_casuali[i]=rand()%51+1;
for(j=a*7;j < i;j++)
if(numeri_casuali[i]==numeri_casuali[j])d=1;
}while(d);
a=a+1;
}


Io dovrei ottenere 7 estrazioni diverse 'n' volte, dove 'n' nel mio programma è rappresentato dalla variabile numero. Queste 7 estrazioni devono essere diverse tra di loro ma possono essere ripetute nelle estrazioni successive. Come ho provato a fare io, ottengo le stesse 7 estrazioni 'n' volte. Come mai?

Scara95
19-05-2014, 19:05
Queste 7 estrazioni devono essere diverse tra di loro ma possono essere ripetute nelle estrazioni successive.
Che significa?!

davix10
19-05-2014, 19:12
Faccio un esempio per rendere l'idea:
numero = 2 allora vuol dire che devo fare 2 estrazioni differenti con ognuna delle quali estrae un numero fisso di 7 numeri quindi...

2 8 25 12 1 9 32

30 25 47 2 50 41 3

Il numero estratto non può essere lo stesso nella stessa estrazione ma può essere uguale a quella precedente e/o successiva.

Scara95
19-05-2014, 20:32
Ti è stato suggeristo un algoritmo più efficiente.
Ad ogni modo in quel codice mancano dichiarazioni e inizializzazione che ne permettono una limitata comprensione. Sicuramente l'uso di srand è scorretto, andrebbe infatti eseguito una sola volta all'inizio del main e probabilmente il problema è proprio dovuto a quella riga di codice.

In ogni caso per il mescolamento degli elementi questo meccanismo è più efficiente:

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>

using namespace std;

template<class CONTAINER_REF>
class Randomizer {
private:
CONTAINER_REF es;
int n;
public:
Randomizer(CONTAINER_REF container): es(container) { n = container.size();}
int getNext() {
int i = rand() % n--;
swap(es.at(i), es.at(n));
return es[n];
}
void reset() {
n = es.size();
}
const CONTAINER_REF shuffle() {
int i;
while(n) {
i = rand() % n--;
swap(es.at(i), es.at(n));
}
return es;
}
};

int main() {
srand(time(NULL));
vector<int> cards(52);
for(int i = 0; i < 52; ++i) {
cards[i] = i+1;
}
Randomizer<vector<int>& > r = Randomizer<vector<int>& >(cards);
r.shuffle();
for(int i = 0; i < 52; ++i) {
cout << cards[i] << "\n";
}
r.reset();
cout << endl;
for(int i = 0; i < 4; ++i) {
for(int j = 0; j < 7; ++j) {
cout << r.getNext() << "\t";
}
cout << endl;
}
return 0;
}

Se vuoi usare un array puoi riadattare facilmente...
Oppure puoi sfruttare array in C++11
Insomma, vedi tu...

davix10
19-05-2014, 21:07
Grazie mille! sei stato gentilissimo! :)

Loading