rand() - losowanie bez powtorzen

0

Witam. Czy przy pomocy funkcji rand() lub jakiejs innej jest mozliwe losowanie liczb by zadna z nich nie powtorzyla sie dwukrotnie? Jezeli tak prosilbym o objasnienie jak tego dokonac ;)

//kod ktory losuje 4 liczby z zakresu od 1 do 4
srand(time(0));
for (int i=1; i<5; i++)
{
int wynik = (1+rand()%4);
cout << wynik << endl;
}</b>
0

Dwie możliwości:

  1. po wylosowaniu sprawdź, czy takiej już nie ma
  2. zamiast losowania zastosuj losowe mieszanie elementów określonego zbioru
0

Zawsze mozesz zastosowac taka sztuczke ;-)
Powiedzmy chcesz losowac liczby z przedzialu 0-99. Tworzysz tablice 100 elementowa, przypisujesz odpowiednie wartosci (tab[0] := 0 itd...)
Potem losujesz random(99). Bierzesz wartosc z tablicy o indeksie wylosowanym (np 14), czyli tab[14]. Potem wartosc z pola tab[99] przepisujesz do tab[14] i znowu losujesz, tylko juz random(98)
Itd...

0
Szczawik napisał(a)

Dwie możliwości:
2. zamiast losowania zastosuj losowe mieszanie elementów określonego zbioru
mozna wiecej na ten temat?

0

Powyżej masz opisane.

Może Twój przykład: chcesz wylosować bez powtórzeń liczby od 1 do 4.

//Wypełnienie tablicy po kolei liczbami 1 - 4
for (int i=0; i<4; i++)
  Tablica[i] = (i+1);

Potem robisz przemieszanie zbioru. Polecam to zrobić kilkakrotnie (ale bez przesady).

//Zamieszanie liczb przez zamienianie elementów "i" (kolejne) oraz "j" (losowane)
for (int i=0; i<4; i++)
{
  j = rand()%4;
  temp = Tablica[i];
  Tablica[i] = Tablica[j];
  Tablica[j] = temp;
}

Poniższy kod powinien wyrzucić Ci na ekran liczby w przemieszanej kolejności.

//Wyświetlenie na ekran liczb w zamienionym porządku
for (int i=0; i<4; i++)
  cout << Tablica[i] << endl;
0

ja robilem to troszke inaczej.... losowalem n-ty element :) . powiedzmy mamy tablice 4 elementowa . wiec pola odpowiednio sa indeksowane od 0..3. losowalem wiec liczbe z tego wlasnie zakresu i... zaznaczalem wylosowane pole jako zajete. przy nastepnym przejsciu pozostalo mi jez 4-1 =3 mozliwosci losowania, wiec odpowiednio zakres zmniejszal sie do 0..2 . wylosowalemi teraz znow zaznaczylem n-te nie zajete pole jako wylosowane... wynikiem losowania nie byla bezposrednio wartosc zwrocona przez rand(), tylko wartosc wtorna - indeks n-tego wolnego pola.
ta metoda ma ta zalete, ze wartosci w tablicy maja znaczenie tylko 0/1 (wylosowane/niewylosowane), a wiec mozna w kazdym bajcie pamieci zmiescic 8 komorek (ale to sobie ew. sam dopiszesz :) )

char tab[]={1,1,1,1}; // char tab[]={0,0,0,0};
int wolne=4;

int losuj(){
  if(!wolne)return -1;
  int i=1+(rand()%wolne);
  int j=0;
  while(i)i-=tab[j++]; // while(i)i-=!tab[j++];
  tab[--j]=0; // tab[--j]=1;
  return j;
}
0

co tu sie dzieje 8-0

a moze po prost uzyj kontenera set?

0

vixen: jakie to ma znaczenie czy operujesz na setach czy tablicach? Idea jest ta sama, a kod i tak dopasuje sobie do własnych potrzeb.

0

A może tak :

randomize();
   for (i=0;i<4;i++)
   {
    gen=random(4)+1;
    for (j=0;j<4;j++)
     if (gentab[j]==gen) gen=0;
        if (gen>0) gentab[i]=gen;
   else i--;
   }
   cprintf("%d",gentab[i]);

Co Ty na to ? Losuje bez powtórzeń w każdym razie :)

0
Szczawik napisał(a)

jakie to ma znaczenie czy operujesz na setach czy tablicach?

  1. mniej kodu
  2. set jest bezpieczniejszy
  3. jest to rozwiaznie proste, nie wymagajace jakichs dziwnych kombinacji
0

Do postu adf88, ktory zniknal po paru minutach ;-)

Klucilbym sie, ze mniej wydajne. Zwiekszenie poziomu abstrakcji wcale nie musi oznaczac spadku wydajnosci.

0

heh, post zniknął po paru sekundach (pisałem ze set'y są minej wydajne od tablic), gdy zrozumiałem, że wcale nie musze mieć racji.

Jakoś nie mam zaufania do setów, wole operować bezpośrednio na bitach.

0

a jak wylosować coś z tablicy? <początkujący>

0

losujesz liczbę naturalną n z zakresu <0, len(tablica)-1>, zakładając indeksowanie od zera, i pobierasz n-ty element tablicy.

0
vixen03 napisał(a)
Szczawik napisał(a)

jakie to ma znaczenie czy operujesz na setach czy tablicach?

  1. mniej kodu
  2. set jest bezpieczniejszy
  3. jest to rozwiaznie proste, nie wymagajace jakichs dziwnych kombinacji

Jest pewna różnica miedzy kodem książkowym, używanym w celu wyjaśnienia zagadnienia, a kodem aplikacji produkcyjnej.
IMHO wymądrzanie się kto by lepiej to napisał, nie jest konieczne.
Pytanie było dość podstawowe i jego autor pewnie jeszcze musi się dużo nauczyć zanim zacznie zwracać uwagę na to jak optymalizować kod.

1 użytkowników online, w tym zalogowanych: 0, gości: 1