prosty program na losowość, wątpliwości

0

Witam, jest taki kod na program, który wygeneruje 5 losowych liczb dla każdego dnia (pon-pt), liczby te nie moge się powtarzać, nie rozumiem tylko dlateczego on działa, losową liczbe generujemy 5 razy-pętla for i potem jest część której nie rozumiem, przypisujemy wartość x do 1 wartości w tabeli, potem do następnej, jak kod sprawdza czy liczby nie są takie same?

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
    int t[5];
    int x;
    srand(time(NULL));

    for (int i=0; i<5;i++)
    {
        do
        {
            x=rand()%35+1;
        }
        while ((t[0]==x)||(t[1]==x)||(t[2]==x)||(t[3]==x)||(t[4]==x));
        t[i]=x;
    }
    cout<<"poniedzialek: "<<t[0]<<endl;
    cout<<"wtorek: "<<t[1]<<endl;
    cout<<"sroda: "<<t[2]<<endl;
    cout<<"czwartek: "<<t[3]<<endl;
    cout<<"piatek: "<<t[4]<<endl;

return 0;
}
0
 while ((t[0]==x)||(t[1]==x)||(t[2]==x)||(t[3]==x)||(t[4]==x)); 

tu masz sprawdzanie, co jest bardzo niewydajne... i do kitu zrobione

Duzo lepiej byloby wygenerowac w vectorze X liczb i pozniej po prostu brac taka liczbe a nastepnie usuwac z kolekcji. Dzieki temu zawsze bedziesz miec losowe liczby a zlozonosc algorytmu bedzie stala. Teraz teoretycznie moze to nigdy sie nie skonczyc (ta petla)

0
do
{
     x=rand()%35+1;
}
while ((t[0]==x)||(t[1]==x)||(t[2]==x)||(t[3]==x)||(t[4]==x)); 

Pętla do-while, czyli po prostu wykonuj lub powtarzaj instrukcję dopóki warunek jest prawdziwy.

Kod losuje x, jeżeli warunek wewnątrz while ((t[0]==x)||(t[1]==x)||(t[2]==x)||(t[3]==x)||(t[4]==x)) == true, czyli któryś element z tablicy jest równy wylosowanemu x, np t[0] == x, to pętla się powtórzy i następuje losowanie nowego x dopóty, dopóki x będzie różne od każdego elementu z tablicy.

Faktycznie jednak takie sprawdzanie jest niepasowne i do kitu.
Zaproponowałbym coś takiego:

for (int i = 0; i < 5; i++)
{
    tab[i] = rand()%35 + 1;
    for (int j = 0; j < i; j++)
    {
        if (tab[i] == tab[j]) i--;
    }
}

Chociaż pewnie istnieje jeszcze lepsze rozwiązanie.

2

ja bym to tak napisał

#include <iostream>
#include <vector>
#include <random>
using namespace std;
 
int main() 
{
	vector<int> listOfNumbers;
	const int maxOfNumbers = 100;
	const int howManyNumbersToSelect = 6;
	for (int index = 0; index < maxOfNumbers; index++)
	{
		listOfNumbers.push_back(index);
	}
 
	std::random_device rd;
    std::mt19937 mt(rd());
    std::uniform_int_distribution<> dist(1, maxOfNumbers);
 
    for(int index = 0; index < howManyNumbersToSelect; index++)
    {
    	int randomNumber = dist(mt) - 1; //because of indexing
    	cout << listOfNumbers[randomNumber] << " ";
    	listOfNumbers.erase(listOfNumbers.begin() + randomNumber);
    }
	return 0;
} 

http://ideone.com/iTjpaI

edit. Mozesz tez zrobic shuffle na vectorze i wypisanie pierwszych N elementow

auto engine = std::default_random_engine{};
std::shuffle(std::begin(listOfNumbers), std::end(listOfNumbers), engine); 
1

Ewentualnie

#include <iostream>
#include <algorithm>
#include <vector>
#include <random>
#include <string>
using namespace std;

int main() {
	
	const vector<string> days = { "pn", "wt", "sr", "czw", "pt" };
	const int nums_per_day = 5;
	const int elements_num = days.size() * nums_per_day;
	
	vector<int> nums(elements_num);
	iota(begin(nums), end(nums), 0);
	shuffle(begin(nums), end(nums), std::mt19937{std::random_device{}()});

	for(auto it = begin(nums); it != end(nums); advance(it, nums_per_day)) {
		cout << days[distance(begin(nums), it)/nums_per_day] << ": ";
		for_each(it, it+nums_per_day, [](auto num) {
			cout << num << " ";	
		});
		cout << endl;
	}
	return 0;
}

http://ideone.com/DAowoC

0

Mały komentarz dla mniej zaawansowanych użytkowników którzy chcieliby wesoło sprawdzić powyższe kody i zauważyli że coś nie bangla, trzeba mieć kompilator zgodny ze standardem C++ 11.

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