rand() - losowanie bez powtorzen

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 ;)

Kopiuj
//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>
SZ
  • Rejestracja:ponad 21 lat
  • Ostatnio:ponad 15 lat
  • Postów:3356
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

Dzięki wszystkim forumowiczom za lata wspólnych dyskusji; miłej zabawy w programowanie!
Sławomir "Szczawik" Włodkowski
PL
  • Rejestracja:około 20 lat
  • Ostatnio:ponad 8 lat
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?

SZ
  • Rejestracja:ponad 21 lat
  • Ostatnio:ponad 15 lat
  • Postów:3356
0

Powyżej masz opisane.

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

Kopiuj
//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).

Kopiuj
//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.

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

Dzięki wszystkim forumowiczom za lata wspólnych dyskusji; miłej zabawy w programowanie!
Sławomir "Szczawik" Włodkowski
flabra
  • Rejestracja:ponad 21 lat
  • Ostatnio:ponad 12 lat
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 :) )

Kopiuj
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;
}

Linuksa, czy innego Uniksa, można opisać za pomocą logiki boolowskiej a nie za pomocą prawdopodobieństwa. 'System szesnastkowy jest wspaniały! W skali od 1 do 10 daję mu E' extreme safety for Ubuntu:
sudo echo -e 'Defaults targetpw\nDefaults timestamp_timeout=0' >> /etc/sudoers
vixen03
  • Rejestracja:ponad 21 lat
  • Ostatnio:prawie 14 lat
  • Postów:475
0

co tu sie dzieje 8-0

a moze po prost uzyj kontenera set?


SZ
  • Rejestracja:ponad 21 lat
  • Ostatnio:ponad 15 lat
  • Postów:3356
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.


Dzięki wszystkim forumowiczom za lata wspólnych dyskusji; miłej zabawy w programowanie!
Sławomir "Szczawik" Włodkowski
0

A może tak :

Kopiuj
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 :)

vixen03
  • Rejestracja:ponad 21 lat
  • Ostatnio:prawie 14 lat
  • Postów:475
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

Malcolm
  • Rejestracja:ponad 22 lata
  • Ostatnio:prawie 9 lat
  • Postów:317
0

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

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


Stwórzmy boga na własne podobieństwo
Niech będzie mały i parszywy,
Wtedy wszyscy w niego uwierzą...
adf88
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 12 lat
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>

dodekam
  • Rejestracja:około 19 lat
  • Ostatnio:prawie 16 lat
0

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


There is no system but GNU, and Linux is one of its kernels.
JID: dodek@jabber.org
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.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.