Newsgroup: it.comp.lang.c++
Titolo: Numeri random senza ripetizione

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!

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
Capitan Catarro ha scritto:


Capitan Catarro wrote:

#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

   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

Fred Mammola e il Tempio di Sdenk Settemani Urrins wrote:
 > Capitan Catarro wrote:
 >> 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;
 >>  }
 > #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 ) );
 >     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: 
james...@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

 
grazie dei suggerimenti!
