2012-07-03 29 views
5

muszę generowane liczb losowych w przedziale [0, 10] takie, że:Generowanie "In-Range" liczb losowych w C

  • Wszystkie numery wystąpić tylko raz.
  • Nie ma powtarzających się wyników.

Czy ktoś może mi wskazać, którego algorytmu użyć?

+7

Generowanie [0, 10) sekwencji i przetasować go. – cnicutar

+3

Po pierwsze, [co próbowaliście?] (Http://whathaveyoutried.com) Po drugie, co to jest, 0-10 lub 1-10? –

+0

Witam Carl, próbowałem generować sekwencję z funkcją rand(), ale nie mogłem osiągnąć wyniku. Po drugie, Zasięg, o którym mowa powyżej, wynosi od 0 do 10. Dzięki –

Odpowiedz

1

Wypróbuj ten algorytm dla liczb pseudolosowych:

int values[11] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 
srand(time(NULL)); 

for (int i = 0; i < 11; i++) 
{ 
    int swap1idx = rand() % 11; 
    int swap2idx = rand() % 11; 

    int tmp = values[swap1idx]; 
    values[swap1idx] = values[swap2idx]; 
    values[swap2idx] = tmp; 
} 

// now you can iterate through the shuffled values array. 

pamiętać, że jest przedmiotem uprzedzeń modulo, ale to powinno działać, czego potrzebujesz.

+0

@lashmais OP nie było jasne, ale naprawione, tak czy inaczej. –

11

Algorytm w odpowiedzi Richarda J. Rossa jest niepoprawny. Generuje on n^n możliwych zamówień zamiast n!. Ten post na blogu Jeff Atwood ilustruje problem: http://www.codinghorror.com/blog/2007/12/the-danger-of-naivete.html

Zamiast tego należy użyć Knuth-Fisher-Yates Shuffle:

int values[11] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 
srand(time(NULL)); 

for (int i = 10; i > 0; i--) 
{ 
    int n = rand() % (i + 1); 

    int temp = values[n]; 
    values[n] = values[i]; 
    values[i] = temp; 
} 
+1

Czy jest to przetasowanie Knutha lub Fisher-Yatesa [http://pl.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle]? Jest również tutaj: http://stackoverflow.com/questions/1150646/card-shuffling-in-c-sharp – slashmais

+0

Ten sam algorytm, ale poprawiłem nazwę. – japreiss

+0

Na stronie Wikipedii jest to aka Knuth-shuffle - powinienem przeczytać intro, a nie tylko przejrzeć szczegóły;) – slashmais

0

spróbuj utworzyć funkcję losowo, tak:

void randomize(int v[], int size, int r_max) { 
    int i,j,flag; 

    v[0] = 0 + rand() % r_max; // start + rand() % end 
    /* the following cycle manages, discarding it, 
the case in which a number who has previously been extracted, is re-extracted. */ 
    for(i = 1; i < size; i++) { 
     do { 
      v[i]= 0 + rand() % r_max; 
      for(j=0; j<i; j++) { 
       if(v[j] == v[i]) { 
        flag=1; 
        break; 
       } 
       flag=0; 
      } 
     } while(flag == 1); 
    } 
} 

Następnie wystarczy nazwać przekazywanie tablicy v[] z 11 elementów, ich rozmiaru, a górny zakres:

randomize(v, 11, 11); 

Tablica, ze względu na to, że jest przekazywana jako argument przez odniesienie, będzie losowana, bez powtórzeń i z cyframi pojawiającymi się jeden raz.

Pamiętaj, aby zadzwonić srand(time(0)); przed wywołaniem randomize i zainicjować int v[11]={0,1,2,3,4,5,6,7,8,9,10};

Powiązane problemy