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

Losowanie bez powtórzeń

VPS Starter Arubacloud
0 głosów
409 wizyt
pytanie zadane 18 stycznia 2020 w C i C++ przez Marcinuq Użytkownik (640 p.)

Witam!

Wiem, że dużo osób zadawało pytanie odnośnie losowania, lecz ja po prostu chcę wiedzieć co w moim kodzie jest źle.

Program losuje liczby, jednak one się powtarzają.

Proszę jeszcze o to, żebyście nie pisali o tym jak można skrócić kod. Po prostu chcę wiedzieć co mam poprawić.  

#include <iostream>
#include <time.h>
using namespace std;

int main()
{
    int ile_liczb; ///ile liczb wylosować
    int do_jakiej; ///do jakiej liczby ma losować

    setlocale(LC_ALL,"");
    srand(time(0));
    cout << "Ile liczb wylosować?" << endl;
    cin >>ile_liczb;
    int tab[ile_liczb];

    cout<<"Do jakiej liczby losować?"<<endl;
    cin>>do_jakiej;
    system("CLS");
    for(int i=0; i<ile_liczb; i++)
    {
        tab[i]=rand()%do_jakiej+1;
        if(i>0)
        {
            for(int j=0; j<i; j++)
            {
                if(tab[i]==tab[j])
                {
                    tab[i]=rand()%do_jakiej+1;
                    j--;
                }
            }
        }
    }

    for(int i=0; i<ile_liczb; i++){cout<<tab[i]<<endl;}

    return 0;
}

 

3 odpowiedzi

0 głosów
odpowiedź 18 stycznia 2020 przez adam_jankowski Mądrala (5,970 p.)
wybrane 25 czerwca 2020 przez Marcinuq
 
Najlepsza
Losowanie wydziel to oddzielnej funkcji, oraz zrób drugą tablicę typu boolean, zawierającą liczbę szufladek równą wartości zmiennej do_jakiej. Chodzi o to, że na przykład, jeżeli tablica[3] jest równa true, oznacza to, że trójka została już wylosowana. W funkcji po wylosowaniu, sprawdzasz czy czasem ta liczba w tablicy nie ma wartości true. Jeśli ma wywolujesz tą samą funkcje jeszcze raz, a jeśli nie ma wartośći true, przypisujesz ją do wylosowanych liczb, oraz zmieniasz wartość w nowej tablicy na true.

 

Mam nadzieję, że pomogłem :)
0 głosów
odpowiedź 18 stycznia 2020 przez amtrax Dyskutant (9,630 p.)
Zdaje sobie sprawę, że ten pomysł jest nieefektywny pod względem czasu, ale może podpasuje;
Co jakby w pętli sprawdzać czy wylosowana liczba jest inna niż pozostałe, jeśli tak to powtórzyć wylosowanie bez zapisania jej do tablicy?

Pozdrowienia
komentarz 18 stycznia 2020 przez Marcinuq Użytkownik (640 p.)
Ale w kodzie, w pętli wewnętrznej to zrobiłem, jeśli liczba jest taka sama to losuje nową liczbę i zmienia wartość j o 1 mniejszą i sprawdza jeszcze raz tą liczbę.
komentarz 18 stycznia 2020 przez amtrax Dyskutant (9,630 p.)

  Zamiast liczbę wylosowana zapisywać  od razu do tablicy, można stworzyć zmienną która w ją przechowuje i tą zmienną porównać dopiero z tablicą, pętla będzie myśle wtedy bardziej przejrzysta. 
Możesz użyć również instrukcji "continue" i "break". 

http://www.algorytm.edu.pl/instrukcja-iteracyjna-ptla/break-continue.html

0 głosów
odpowiedź 18 stycznia 2020 przez Marcin Siniarski Gaduła (4,420 p.)

Nie sprawdzasz czy ile_liczb jest większy lub równe do_jakiej.
Pomyśl, masz do wylosowania 10 unikatowych całkowitych liczb w zakresie od 1 do 9 (jest to nie możliwe)

Twoja pętla nie działa.
O wiele prostszym rozwiązaniem będzie używanie flagi aby zaznaczyć aktualną liczbę za unikatową i jeśli nie jest wylosowanie nowej.

Jeśli potrzebujesz dalszej pomocy, mogę wysłać ci rozwiązanie.
Powodzenia

komentarz 18 stycznia 2020 przez Marcinuq Użytkownik (640 p.)

1.Wiem ,że nie sprawdzam czy ile_liczb jest większy lub równe do_jakiej, ale nie jest to mi potrzebne.

2.Losuje od 1 do 10(a nie do 9 dla twojej informacji)

3.Po prostu chcę żeby ta pętla działa, która sprawdza czy te liczby są różne.

 

komentarz 19 stycznia 2020 przez tkz Nałogowiec (42,000 p.)

Nie sprawdzasz po prostu pozycji równej i w pętli. Warunek jest do i, nie włącznie z i.

for(int j=0; j<i; j++)

Zauważ, że jak masz w tablicy na miejscu Y wartość X, to porównanie jest do Y-1, czyli, czy chcesz, czy też nie, nie porównasz wszystkich wartości, zawsze umknie jedna. 

komentarz 19 stycznia 2020 przez Marcinuq Użytkownik (640 p.)
To jak mam zrobić żeby wszystko mi porównało?
komentarz 19 stycznia 2020 przez Marcin Siniarski Gaduła (4,420 p.)
int ile_liczb; // ile liczb wylosować
    int do_jakiej; // do jakiej liczby ma losować

    setlocale(LC_ALL,"");
    srand(time(0));
    cout << "Ile liczb wylosowac?" << endl;
    cin >>ile_liczb;

    cout<<"Do jakiej liczby losowac?"<<endl;
	do {
		cout << '[' << ile_liczb << " <= ? ]\n => ";
		cin>>do_jakiej;
	} while(do_jakiej < ile_liczb);
	system("CLS");
	
	int tab[ile_liczb];
	
	for(int i=0; i<ile_liczb; i++)
	{
		bool isUnique = true;
        int n =rand()%do_jakiej+1;
		
        for(int j=0; j<i; j++)
        {
            if(n==tab[j])
            {
				isUnique = false;
				break;
			}
        }
		
		if(!isUnique) {
			i--;
		} else {
			tab[i] = n;
		}
    }

 

1
komentarz 19 stycznia 2020 przez tkz Nałogowiec (42,000 p.)
int main()
{
    std::mt19937 random{std::random_device{}()};
 
    std::unordered_set<int> selected;
    std::uniform_int_distribution dis(0, 1000000000);
    while(selected.size() < 100)
        selected.insert(dis(random));
 
    std::copy(selected.begin(), selected.end(), std::ostream_iterator<int>(std::cout, "\n"));
}

 

Podobne pytania

+1 głos
2 odpowiedzi 1,081 wizyt
pytanie zadane 7 stycznia 2016 w C i C++ przez Tony Początkujący (360 p.)
0 głosów
1 odpowiedź 771 wizyt
pytanie zadane 18 października 2018 w C i C++ przez Gadzic Nowicjusz (170 p.)
0 głosów
1 odpowiedź 396 wizyt
pytanie zadane 9 października 2018 w C i C++ przez Gadzic Nowicjusz (170 p.)

92,455 zapytań

141,263 odpowiedzi

319,099 komentarzy

61,854 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!

...