Jump to content

Witaj!

Zaloguj lub Zarejestruj się aby uzyskać pełny dostęp do forum.

Photo
- - - - -

Losowe liczby nie powtarzajace sie


  • Please log in to reply
3 replies to this topic

#1 Zuki

Zuki
  • 434 posts
  • SkądPrzeworsk

Posted 05 March 2011 - 11:20

Witam
Chce chce by program losował mi 35 liczb nie powtarzających się, udało mi się stworzyć coś takiego:
int unique = 0;
	int numbers[35];
	
	for (int i = 0; i < 35; i++) {
		numbers[i] = 0;
	}
	
	while (unique < 35) {
		int x = arc4random() % 35;
		if (numbers[x] == 0) {
			numbers[x] = 1;
			++unique;
		}
	}
	
	for (int i = 0; i < 35; i++) {
		if (numbers[i] == 1) {
			NSString *str = [NSString stringWithFormat: @"%d", i];
			NSLog(@"%@", str);
		}
	}

lecz problem w tym iż chce by te liczby były w kolejności losowej a nie po kolei ...

#2 tmkszlc

tmkszlc

  • 1846 posts
  • SkądSzczecin, PL

Posted 05 March 2011 - 11:35

funkcja rand() zapewne istnieje, sprawdz dokumentację.

#3 Roberto

Roberto
  • 13752 posts
  • SkądWrocław

Posted 05 March 2011 - 12:08

masz kilka wyjść.
w zależności od tego co jest priorytetem.

aktualnie - wypełniłbym tę tablicę -1 a nie 0 (bo 0 w końcu można wylosować)
i możesz losować indeks, jeżeli wartość == -1 to wtedy
numbers[x] = unique++;

tylko to ma jeden spory minus - nie wiadomo ile będzie trwać (jak ci zostanie 1 niezapełniony element, to musisz czekać aż akurat ten indeks wylosuje, a to już sprawa losowa i szansa wynosi 1/35 za każdym razem).

możesz więc sobie stworzyć tablicę z liczbami od 0 do 34 (zamiast same 0 czy same -1) i zrobić np. X losowych swapów (zamiany elementu o indeksie losowym z innym elementem o indeksie losowym) co powinno ci wymieszać tablicę.
+ jest tutaj określony czas działania tego
minusem może być średnia losowość tego (chociaż przy określonej liczbie swapów powinno się ładnie wymieszać)

jak robisz w Obj-C to możesz też stworzyć tablicę z tymi liczbami (NSMutableArray) i 35 razy wyjąć (usunąć z niej) z niej losowy element (losowy - o indeksie od 0 do [tablica count]) a jego wartość wpisać do swojej tablicy.

możesz też to zrobić na 2 zwykłych tablicach, tylko wtedy po wyjęciu losowego indeksu musisz przesunąć wszystkie elementy "wyżej" o 1 w dół. troszeczkę roboty, ale też definitywnie skończony czas działania i w pesymistycznym wypadku nie jest wcale taki spory.

znaj dobre serce:
#define ILE 35
	int temp[ILE];
	int numbers[ILE];
	
	for (int i = ILE - 1; i >= 0; --i) {
		temp[i] = i;
	}
	srand(time(0));
	int x;
	for (int index = 0; index < ILE;) {
		x = rand()%(ILE-index);
		numbers[index++] = temp[x];
		for (int j = x; j <= ILE - index;) {
			temp[j] = temp[++j];
		}
	}
	
	for (int i = 0; i < ILE; ++i) {
		printf("%d\n", numbers[i]);
	}

chociaż swap'owanie wydaje się (jeżeli chodzi o złożoność - czasową i pamięciową) lepsze i daje całkiem dobre wyniki (przy całkiem małej liczbie swap'ów):
#define ILE 35
	#define ZMIAN 20
	int numbers[ILE];
	
	for (int i = ILE - 1; i >= 0; --i) {
		numbers[i] = i;
	}
	srand(time(0));
	int temp;
	int a;
	int b;
	for (int i = ZMIAN; i != 0; --i) {
		a = rand()%ILE;
		b = rand()%ILE;
		temp = numbers[a];
		numbers[a] = numbers[b];
		numbers[b] = temp;
	}
	for (int i = 0; i < ILE; ++i) {
		printf("%d\n", numbers[i]);
	}

tmkszlc - od kiedy rand zapewnia niepowtarzające się liczby?

#4 Zuki

Zuki
  • 434 posts
  • SkądPrzeworsk

Posted 05 March 2011 - 12:52

wielkie dzięki ! jesteś wielki :)




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users