Liczby losowe nie powtarzające się

0

Witam... Mój problem polega na tym że:
Mam już napisany gotowy program na losowanie liczb od 1 do 80 ale nie umiem zrobić tak żeby te liczby się nie powtarzały... Czy pomoże ktoś ?? w tym miejscu mam problem: cyfry [i]=rand ()%80+1; i nie wiem co mam tu dopisać dalej... :(

0

użyj szukaj, było milion razy na forum

0

Ale co wpisać tak dokładnie ??

0

Zrób tablicę na 80 miejsc z flagami mówiącymi czy liczba była już wylosowana czy jeszcze nie.

0
int losuj()
{
	int los;
	srand(static_cast<int>(time(0)));
		los=rand() % 52;
	return los;
}


*****
         bool sprawdz[80];
         int temp;

	 for(int i=1;i<=80;i++)	
	 {
	   temp=losuj();
		if(sprawdz[temp]==true)
		{
			player2[i]=temp;
			sprawdz[temp]=false;
		}
		else
			i--;
	 }
1
Sid_ napisał(a)
int losuj()
{
	int los;
	srand(static_cast<int>(time(0)));
		los=rand() % 52;
	return los;
}


*****
         bool sprawdz[80];
         int temp;

	 for(int i=1;i<=80;i++)	
	 {
	   temp=losuj();
		if(sprawdz[temp]==true)
		{
			player2[i]=temp;
			sprawdz[temp]=false;
		}
		else
			i--;
	 }

Piękny kod, szkoda, że nadaje się co najwyżej na The Daily WTF. Cały problem polega na tym, że co iterację inicjalizujesz generator pseudolosowy - będziesz otrzymywał te same wyniki póki wartość ziarna się nie zmieni. Wartość ziarna zależna jest od funkcji time, która zwraca aktualny czas w sekundach - zmiana wyniku funkcji rand będzie następować tylko raz na sekundę. Wykonanie tych 80 iteracji zajmie w najlepszym razie 80 sekund, znając jednak proste generatory to może się nie skończyć nigdy.

O niewłaściwym inicjalizowaniu i indeksowaniu tablic może lepiej nic mówił nie będę?

0
donkey7 napisał(a)

Zrób tablicę na 80 miejsc z flagami mówiącymi czy liczba była już wylosowana czy jeszcze nie.

LOL. Z takim algorytmem to po kilkudziesięciu losowaniach można się nie doczekać kolejnej liczby.

0
#include <cstdlib>
#include <iostream>
#include <time.h>

using namespace std;

int main()
{
    const int MAX = 80;
    int MaxLos;
    int i ,ile ,index;
    srand(time(0));
    int cyfry[MAX];
    for (i = 0 ; i<MAX ; i++)
    
    cyfry[i] = i+1;
    
    cout <<"Ile liczb chcesz wylosowac :";
    cin >> ile;
    MaxLos = MAX-1;
    
    for (i = 0 ; i< ile ; i++ )
    {
        index = rand()%MAX +1;
        cout << cyfry[index] << ", ";
        cyfry[index] = cyfry[MaxLos];
        MaxLos --;
        
    }
    
    system("PAUSE");
    return EXIT_SUCCESS;
}
0
Piotrekdp napisał(a)
#include <cstdlib>
#include <iostream>
#include <time.h>

using namespace std;

int main()
{
    const int MAX = 80;
    int MaxLos;
    int i ,ile ,index;
    srand(time(0));
    int cyfry[MAX];
    for (i = 0 ; i<MAX ; i++)
    
    cyfry[i] = i+1;
    
    cout <<"Ile liczb chcesz wylosowac :";
    cin >> ile;
    MaxLos = MAX-1;
    
    for (i = 0 ; i< ile ; i++ )
    {
        index = rand()%MAX +1;
        cout << cyfry[index] << ", ";
        cyfry[index] = cyfry[MaxLos];
        MaxLos --;
        
    }
    
    system("PAUSE");
    return EXIT_SUCCESS;
}

Powyższy kod z pewnością nie działa(sprawdziłem i dał dwa razy tą samą liczbę a poza tym rand()%MAX może zwrócić MAX-1 i jak dodamy jeden to index będzie równy MAX i wyjdziemy poza zakres tablicy) .
Tu jest mój kod:

#include <set>
#include <iostream>
#include <cstdlib>

using namespace std;
set<int> S;
int losuj(int zakres)
{
int los=-1;
while(S.find(los) !=S.end())
        los = rand()%zakres;
S.insert(los);
return los;
}

int main()
{
    S.insert(-1);
    int zakres,liczba;
    cin >> zakres >> liczba;
    srand(time(NULL));
    if(!(liczba > zakres))
    for(int i=0;i<liczba;++i)
            cout << losuj(zakres) << endl;

    return 0;
}
0

Szukałem właściwie czegoś innego i tak trafilłem na ten temat. Kiedyś potrzebowalem taki programik do nauki testów. Było okolo 1000 pytań. Ucząc się chciałem odpowiadać na nie w losowej kolejności i oczywiście nie chciałem żeby te pytania się powtarzały, więc napisałem prosty programik w Pascalu. Jak się zacząłem uczyć C++ to w ramach nauki stworzyłem taki programik w C++. Program wyświetla liczby od 1 do 5 w losowej kolejności, ale zasada działania jest zawsze taka sama:

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

int main ()
{
	unsigned uLiczba[5], uLos, i = 0;
	while (i < 5) uLiczba[i] = ++i;
		
	cout << "Wylosowane liczby to:";
	srand (static_cast<unsigned>(time(NULL)));
	while (i > 0)
	{
		uLos = rand() % i;
		cout << " " << uLiczba[uLos];
		uLiczba[uLos] = uLiczba[--i];
	}
	
	cout << endl;
}

Program działa w pewnym sesnsie na zasadzie maszyny losującej Lotto tzn. tworzy tablicę liczb które chcemy losować. Losuje liczbę z tej tablicy i wyświetla ją na ekranie. Ponieważ wylosowana liczba nie jest już nam potrzebna (bo nie chcemy żeby została powtórnie wylosowana) jest zastępowana ostatnią liczbą z tej tablicy, a zakres losowania zmniejsza się o jeden.

0
rnd napisał(a)
donkey7 napisał(a)

Zrób tablicę na 80 miejsc z flagami mówiącymi czy liczba była już wylosowana czy jeszcze nie.

LOL. Z takim algorytmem to po kilkudziesięciu losowaniach można się nie doczekać kolejnej liczby.

No to może powiesz że tablice haszujące też działają szokująco wolno (bo w końcu kolejne generowane hasze mogą nie trafić w wolne miejsca).

Głównym problemem jest tutaj ile liczb jest losowanych. Jeśli ilość losowanych liczb jest bliska mocy całego uniwersum możliwych liczb to najlepiej te liczby losowo spermutować, a potem wypisać żądaną ich ilość. W innym przypadku lepiej posłużyć się techniką z flagami. W ten sposób zawsze dostajemy czas liniowy ze względu na ilość losowanych liczb.

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