Elektroda.pl
Elektroda.pl
X

Wyszukiwarki naszych partnerów

Wyszukaj w ofercie 200 tys. produktów TME
Proszę, dodaj wyjątek elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[C++] Losowanie bez powtórzeń

pentagramsss 18 Maj 2009 23:19 7795 8
  • #1 18 Maj 2009 23:19
    pentagramsss
    Poziom 16  

    Witam
    Gdy losuje sobie np w multilotku 20 liczb to zawsze jakaś się powtórzy ;/ próbowałem, dodawałem np. srand((unsigned)time(NULL)); itd i nie wychodzi ;(

    Code:

    #include <cstdlib>
    #include <iostream>
    #include<set>
    #include <time.h>
    #include <ctime>
    //#include <vector>
    //#include <conio.h>
    #include <windows.h>




    using namespace std;


    void toto(int ile, int z_ilu_liczb)
        {
        srand((unsigned)time(NULL));     
        for(int a=0; a<ile; a++)
        {                         
        cout<<""<<rand()% z_ilu_liczb+1; <<" ";
        }
     };

    int main()
    {
      srand((unsigned)time(NULL));

       int powtorzyc;
       do {
        int licznik,ile,liczby,opcja,z_ilu_liczb;
        //Sleep(1000);
        cout<<"\n\n\t\t\t TOTOLOTEK\n\n";
        cout<<"\n\n\t1 - DUZY LOTEK";
        cout<<"\n\n\t2 - EXPRES LOTEK";
        cout<<"\n\n\t3 - MULTI LOTEK";
        cout<<"\nWybierz opcje: ";
        cin>>licznik;
        system("cls"); 
       
        switch(licznik)
              {
     case 1:
        cout<<"\n\n\tDUZY LOTEK\n\n";
        toto(6,49);
        break;
      case 2:
        cout<<"\n\n\tEXPRES LOTEK\n\n";
        toto(5, 42);
        break;
      case 3:
        cout<<"\n\n\tMULTI LOTEK\n\n";
        toto(20,80);
        break;
       
      default: cout<<"\n\n\tBLEDNE DANE"; 
       }
       cout<<"powtorzyc? t/n"<<endl;
       cin>>powtorzyc;
       }
         while(powtorzyc=1);
     
     
     
         cout<<"\n\n";
         system("pause");
         return 0;

    }


    Proszę umieszczać kod w znacznikach [code] - poprawiłem.
    Poprawiłem temat.
    [Dr.Vee]

  • #2 19 Maj 2009 00:23
    Dr.Vee
    VIP Zasłużony dla elektroda

    No a jak rzucisz 6 razy kostką to też się czasem wynik powtórzy, nie?

    Twój program implementuje losowanie z powtórzeniami, a w grach lotto masz losowanie bez powtórzeń (kule nie są zwracane do puli po wylosowaniu).

    Najprościej mieć tablicę liczb do wylosowania i liczbę elementów w tej tablicy. Po wylosowaniu elementu przenosisz go na koniec tablicy i zmniejszasz licznik elementów - w ten sposób raz wylosowany element już się nie powtórzy:

    Code:
    #include <algorithm>
    
    #include <iostream>
    #include <cstdlib>

    void lotto(unsigned ile, unsigned zIlu)
    {
        unsigned niewylosowane[zIlu];

        for (unsigned i = 1; i <= zIlu; ++i)
            niewylosowane[i-1] = i;

        for ( ; ile; --ile, --zIlu)
        {
            unsigned indeks = std::rand() % zIlu;
            std::cout << niewylosowane[indeks] << " ";   
            std::swap(niewylosowane[indeks], niewylosowane[zIlu-1]);
        }
    }
    Pozdrawiam,
    Dr.Vee

  • #3 19 Maj 2009 00:26
    pawelhabas
    Poziom 9  

    Jasne że się powtórzy, bo taka jest specyfikacja funkcji rand() losuje z powtórzeniami. Aby temu zapobiec musiałbyś napisać inaczej program, ja proponowałbym coś takiego - utworzyć sobie tablicę z 49 liczbami od 1 do 49 (dla dużgo lotka), a funkcji rand używać do wskazania indeksu w tej tablicy. Gdy jakiś element zostanie wskazany wykreślamy go z tablicy, a gdy funkcja rand wskaże to miejsce ponownie to albo losujemy jeszcze raz albo wskazujemy pierwszy nie usunięty bezpośrednio za wskazanym.

  • #4 19 Maj 2009 00:44
    pentagramsss
    Poziom 16  

    czyli mam zrobić tablice jedno wymiarową i sprawdzać czy dana liczba się powtórzyła?

  • #5 19 Maj 2009 09:47
    ed-ek
    Poziom 34  

    pentagramsss napisał:
    czyli mam zrobić tablice jedno wymiarową i sprawdzać czy dana liczba się powtórzyła?

    Dr.Vee podał Ci funkcję lotto(...) dokonującą losowania. Jest to najlepszy algorytm jaki znam. Ale to tylko fcja, dodaj główne ciało programu wywołujące tą fcję, zatrzymywanie ekranu po wyświetleniu wyniku i jeżeli chcesz aby za każdym razem prog. losował inne liczby, fcję srand(....).

  • #6 19 Maj 2009 11:52
    Dr.Vee
    VIP Zasłużony dla elektroda

    Jak się nie wytłumaczysz, to napisz sobie sam.
    1) musisz zapamiętać liczby, które możesz wylosować.
    2) musisz losować jedną z nich
    3) musisz ją usunąć z liczb możliwych do wylosowania.

    Najprostszy i najbardziej nieefektywny algorytm umieszczałby wylosowane liczby w tablicy. Przy wylosowaniu nowej liczby przeglądałby tablicę i sprawdzał, czy już taką wcześniej wylosował. Jeśli nie, to wstaw ją do tablicy, jeśli tak, to losuj do skutku :)

    Proste, ale może długo działać ;)

    Pozdrawiam,
    Dr.Vee

  • #7 19 Maj 2009 12:09
    pentagramsss
    Poziom 16  

    zapisanie do tablicy jest proste... hmmm a sprawdzać za każdym razem for'em?

  • #8 19 Maj 2009 12:17
    ed-ek
    Poziom 34  

    Nie zauważyłem że odpowiadam na post umieszczony w koszu. Odpowiedziałem:
    To jest najbardziej eleganckie!
    To dotyczyło kodu podanego przez Dr.Vee

  • #9 19 Maj 2009 12:23
    pentagramsss
    Poziom 16  

    ed-ek napisał:
    To jest najbardziej eleganckie!

    masz na myśli zapisywanie i sprawdzanie ;]?

 Szukaj w ofercie
Zamknij 
Wyszukaj w ofercie 200 tys. produktów TME