• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Zadanie Losowanie Lotto

VPS Starter Arubacloud
0 głosów
2,888 wizyt
pytanie zadane 12 maja 2018 w C i C++ przez qlucha Obywatel (1,790 p.)

Witam , dawno mnie mnie było na forum , witam ponownie smileyyes . 

Mam pytanie odnośnie zdania , losowanie lotto , prosiłbym o ocene kodu , czy rozwiązanie jest dobre czy można to zrobić lepiej , kod sam napisałem , starałem się wykorzystać wiedze zdobytą z kursu . (Główny problem jaki tu powstaje to powtarzajace sie te same wylosowane liczby , ktróre nie mogą sie powtarzać) .

Prosiłbym o konstruktywną krytyke, co można zrobić lepiej i czy wogóle jest taka potrzeba.

Oto kod dla zainteresowanych :

#include <iostream>
#include <windows.h>
#include <time.h>

using namespace std;

int liczba, Liczby[6];
bool check = 1;

int main()
{
    cout << "Losowanie lotto" << endl <<endl;

    srand(time(NULL));

    // Losowanie Liczb 6 z 49
    for (int i = 0; i < 6; i++) {

        liczba = rand()%49 + 1;
        Liczby[i] = liczba;
    // Porownanie liczb czy sa rozne od siebie
        if (i >= 1){

            for (int j = i ; j > 0; j --) {

                if (liczba == Liczby[j-1]) check = false;
            }
        }

        if (check == false) i--;
        check = 1;

    }

    //Wyswietlenie wynikow
    for (int k = 0; k <6 ; k++) {

        cout << Liczby[k] <<" - ";
    }



    return 0;
}

 

komentarz 28 maja 2018 przez Qizot Nowicjusz (100 p.)

Wszędzie mówią, że rand() jest mało pseudolosowe więc przedstawiam ci rozwiązanie przy pomocy narzędzi z biblioteki <random> z c++11.

#include <iostream>
#include <random>
#include <vector>
#include <algorithm>
#include <iterator>
#include <ctime>
#include <chrono>

using namespace std;

int main()
{
    //unsigned int seed1 = time(NULL);
    //unsigned int seed2 = chrono::system_clock::now().time_since_epoch().count();

   

    //WARNING random_device dla niektorych kompilatorow moze
    //zwracac zawsze ta sama wartosc, np dla code blocka przez co wyniki losowan zawsze beda takie same
    //jesli tak, to rozwaz inne metody seedowania dla generator mt19937
    // np unsigned int seed1 = time(); tylko wtedy losowosc jest mozliwa dopiero co sekunde
    // seed2 jest wtedy lepszym wyborem
    // seedujesz tak: mt19937{seed}

    vector<int> liczby(49);
    iota(begin(liczby), end(liczby), 1); // wypelnienie wektora liczbami od 1 do 49
    shuffle(begin(liczby), end(liczby), mt19937{random_device{}()); // odpalenie maszyny losujacej. przemieszanie wszystkich elementow

    vector<int> wyniki;
    copy_n(begin(liczby), 6, back_inserter(wyniki));

    sort(begin(wyniki), end(wyniki));

    for(auto i : wyniki)
        cout << i << " ";
}

 

2 odpowiedzi

+1 głos
odpowiedź 12 maja 2018 przez niezalogowany
  1. srand jest z cstdlib
  2. ctime, a nie time.h
  3. Nie musisz wyciągać dodatkowego warunku i >= 1. Zostanie on już sprawdzony w pętli przy j > 0. Będzie ten sam efekt.
  4. Gdy znajdzie się jakiekolwiek powtórzenie od razu można przerwać pętlę.
  5. Dodatkowa zmienna liczba jest niepotrzebna
#include <iostream>
#include <cstdlib>
#include <ctime>

int main() {
	std::srand(std::time(NULL));
	int liczby[6];

	std::cout << "Losowanie lotto\n\n";
	// Losowanie Liczb 6 z 49
	for (int i = 0; i < 6; i++) {

		liczby[i] = rand() % 49 + 1;

		// Porownanie liczb czy sa rozne od siebie
		for (int j = i - 1; j > 0; j--) {
			if (liczby[i] == liczby[j]) {
				i--;
				break; // przerwanie pętli
			}
		}
	}

	//Wyswietlenie wynikow
	for (int k = 0; k < 6; k++) {
		std::cout << liczby[k] << " - ";
	}
}
komentarz 12 maja 2018 przez qlucha Obywatel (1,790 p.)

ok dziekismileyyes

komentarz 12 maja 2018 przez qlucha Obywatel (1,790 p.)
edycja 12 maja 2018 przez qlucha
Jeszcze chciałem spytać , czemu lepiej stosować ctime zamiast time.h .

Oraz czy return 0;   na koncu funkcji main() jest wymagany ???
komentarz 12 maja 2018 przez j23 Mędrzec (194,920 p.)
edycja 12 maja 2018 przez j23

Dla zachowania konwencji... W C++ zamiast srand i rand powinieneś użyć klas z biblioteki <random>, czyli std::random_device, np. std::default_random_engine i std::uniform_int_distribution.

 

PS. użyj funkcji std::random_shuffle.

komentarz 12 maja 2018 przez niezalogowany
edycja 12 maja 2018

Pliki nagłówkowe z biblioteki standardowej kończące się na ".h" są z języka C i są uznawane za zdeprecjonowane (time.h, stdlib.h, math.h....). Mają swoje odpowiedniki z nazwą zaczynającą się na "c"  (cmath, cstdio, ctime). Często jedyną różnicą jest to, że ich elementy znajdują się w przestrzeni nazw std. Natomiast zdarza się, że różnią się od siebie zachowaniem czy liczbą parametrów (np odpowiednie wersje strchr, memchr, atexit, exit, abs, div ...). Natomiast przestrzeni nazw zapobiegają kolizji nazw.

Funkcja main i tak zwróci 0 nawet bez instrukcji return.

komentarz 12 maja 2018 przez qlucha Obywatel (1,790 p.)

Znalazłem małego bug'a , przeoczenie w kodzie , Liczby nadal sie powtarzały .

Wykonałem test dla zakresu od 1 do 7

  std::cout << "Losowanie lotto\n\n";
    // Losowanie Liczb 6 z 7
    for (int i = 0; i < 6; i++) {
 
        liczby[i] = rand() % 7 + 1;
 
        // Porownanie liczb czy sa rozne od siebie
        for (int j = i - 1; j > 0; j--) {
            if (liczby[i] == liczby[j]) {
                i--;
                break; // przerwanie pętli
            }
        }
    }

Zmieniłem na for (int j = i - 1; j >= 0; j--)                 powinno być  j>=0

Proszę sprawdz czy mam racje . dzieki.smileyyes

komentarz 12 maja 2018 przez niezalogowany

O faktycznie smiley

komentarz 12 maja 2018 przez qlucha Obywatel (1,790 p.)

yes dzieki za pomoc . Dzisiaj też sie nauczyłem czegoś nowego , chociaż ogrom wiedzy jescze przedemną ...

0 głosów
odpowiedź 17 listopada 2019 przez mmarszik Mądrala (7,390 p.)

Można też bez sprawdzania czy liczba się powtarza, usuwamy wylosowaną:

 

#include <cstdlib>
#include <random>
#include <iostream>
#include <vector>

int main(int argc, char *argv[]) {
    const int seed = (int)time(NULL);
    std::cout << "seed = " << seed << std::endl;
    std::ranlux48 rnd( seed );
    std::vector<int> liczby;
    for( int i=0 ; i<49 ; i++ ) {
        liczby.push_back( i + 1 );
    }
    for( int i=0 ; i<6 ; i++ ) {
        int r = rnd() % liczby.size();
        std::cout << liczby[r];
        if( i < 5 ) {
            std::cout << ", ";
        }
        liczby[r] = liczby[ liczby.size()-1 ];
        liczby.pop_back();
    }
    std::cout << std::endl;
    return 0;
}

 

Podobne pytania

+1 głos
2 odpowiedzi 198 wizyt
pytanie zadane 8 lutego 2020 w JavaScript przez Dev26 Nowicjusz (130 p.)
0 głosów
2 odpowiedzi 220 wizyt
pytanie zadane 29 sierpnia 2017 w HTML i CSS przez DraveS Początkujący (300 p.)
0 głosów
1 odpowiedź 221 wizyt
pytanie zadane 20 sierpnia 2017 w PHP przez Smatix Obywatel (1,050 p.)

92,451 zapytań

141,261 odpowiedzi

319,073 komentarzy

61,853 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...