2010-03-03 20 views
10

के साथ एक सरणी भरना मैं यादृच्छिक अनुक्रम में 1-20 से संख्याओं के साथ 20 इंच की एक सरणी भरने की कोशिश कर रहा हूं।यादृच्छिक संख्या

int lookup[20]={0}; 
int array[20]={0}; 
srand(time(NULL)); 
for(int i=0;i<20;++i){ 
    bool done=false; 
    while(!done){ 
     int n=rand()%20; 
     if(lookup[n]==0){ 
      array[i]=n; 
      lookup[n]=1; 
      done=true; 
     } 
    } 
} 

मैं अगर यादृच्छिक संख्या अभी तक चुना है और सरणी में यह संग्रहीत नहीं है की जाँच करने के लिए एक देखने सरणी बना लिया है: यहाँ मेरी कोड है। जैसा कि आप देख सकते हैं कि मैंने 2 लूप बनाए हैं, एक ट्रैवर्सिंग सरणी के लिए और यादृच्छिक संख्या चुनने के लिए थोड़ी देर के लिए। प्रत्येक लूप पुनरावृत्ति में संख्या फिर से दिखाई दे सकती है और लूप के दौरान एक और कारण हो सकती है। क्या ऐसा करने का कोई तेज तरीका है?

+0

यादृच्छिक-संख्या-जनरेटर टैग –

+0

लागू करें यह भी देखें: http://stackoverflow.com/questions/1218155/random-number-but-dont-repeat, http://stackoverflow.com/questions/1816534/random -प्लेलिस्ट-एल्गोरिदम, http://stackoverflow.com/questions/417831/what-is-the-best-way-of-randomly-re-arranging-a-list-of-items-in-c, http://stackoverflow.com/questions/813935/randomizing-elements-in-an-array – outis

उत्तर

19

आप सरणी को अनुक्रम में भर सकते हैं और फिर इसे घुमा सकते हैं। इससे 20 से अधिक यादृच्छिक संख्या पीढ़ियों को कभी भी रोकना पड़ेगा।

Fisher-Yates shuffle: ओ (एन) समय में किया जा सकता है।

विकिपीडिया से:

ठीक से लागू, फिशर-येट्स फेरबदल, निष्पक्ष है ताकि हर क्रमचय समान रूप से होने की संभावना है। एल्गोरिदम का आधुनिक संस्करण भी कुशल है, जिसके लिए सामानों की संख्या को आनुपातिक और केवल अतिरिक्त संग्रहण स्थान की आवश्यकता होती है।

+1

+1 वास्तव में! Knuth Shuffle। –

+0

यदि आप विशेष रूप से सी नहीं हैं और सी नहीं हैं तो graham.reeds सुझाव std का उपयोग करने के लिए सुझाव: random_shuffle आपको शफल एल्गोरिदम लागू करने में गलती करने के खतरे के बिना जाना होगा। यदि आप सी का उपयोग कर रहे हैं तो विकिपीडिया पेज (और वेब पर कहीं और संभावना) पर एक कोड कार्यान्वयन है जिसे आप प्रतिलिपि बना सकते हैं। – sfg

+0

हां! मैं इसके लिए सी ++ का उपयोग कर रहा हूँ। std :: random_shuffle जाने के लिए अच्छा है, लेकिन मुझे लगता है कि मैं शफल एल्गोरिदम लागू करने का प्रयास कर रहा हूं। उत्तर के लिए धन्यवाद। – James

0

मैं एक सरणी में 20 यादृच्छिक संख्या डाल चाहते हैं, तो, तरह एक सरणी एक और 20 तत्व सरणी के लिए प्रतिलिपि बनाएँ, और क्रमबद्ध सरणी में प्रत्येक संख्या के लिए, अवर्गीकृत सरणी में इसी नंबर मिल जाए, और डाल वहां के सूचकांक।

+0

इसकी ओ (एन * एन) सही है? –

9

आप 20 1 से संख्या के साथ एक सरणी को भरने और प्रयोग std::random_shuffle

टिप्पणी आप उस बात के लिए एक सरल सरणी करना होगा के लिए एक वेक्टर की जरूरत नहीं है हो सकता है।
उदाहरण:

#include <iostream> 
#include <algorithm> 

using namespace std; 

int main(void) 
{ 
     int array[] = { 0, 1, 2, 3, 4 }; 

     srand(unsigned(time(NULL))); 

     random_shuffle(array, array+5); 

     for(int i=0; i<5; i++) 
       cout << array[i] << endl; 

     return 0; 
} 
1

वहाँ एक बहुत ही लंबी चलने वाली लूप के अपने कोड में संभावना है। यदि आप थोड़ी देर के अंदर हैं (! किया गया) लूप के पास कोई गारंटी नहीं है कि आप कभी खत्म कर लेंगे। स्पष्ट रूप से 20 तत्वों की एक सरणी के साथ यह अभ्यास में एक मुद्दा नहीं होगा लेकिन यदि आप इसे हजारों तत्वों तक स्केल करते हैं तो इससे समस्याएं पैदा हो सकती हैं।

एक और विश्वसनीय समाधान क्रमशः सरणी को भरने के लिए होगा और फिर इसे बाद में घुमाएगा।

+0

"कोई गारंटी नहीं है कि आप कभी खत्म कर देंगे" - लूप यादृच्छिक संख्या के साथ समाप्त हो जाता है यदि यादृच्छिक संख्या फ़ंक्शन पर्याप्त है, लेकिन आप काफी सही हैं कि रनटाइम खराब है। ऐसे मामले में जहां सरणी की लंबाई RAND_MAX से अधिक है, आपको स्पष्ट रूप से एक समस्या है, लेकिन वास्तव में यह डोडी तरीके से करना है कि कोड 0 से यादृच्छिक संख्या प्राप्त करने का प्रयास करता है .. समान वितरण वाले एन -1। एक फिशर-येट्स जो 'एनएंड') एन एन –

+0

के लिए भी कमजोर होगा, यदि आप 1 मिलियन तत्व कहने के लिए स्केल करते हैं तो यह सही होगा, इसमें निश्चित रूप से कुछ प्रदर्शन समस्याएं होंगी। – James

15

std::random_shuffle और std::vector पर देखें।

+0

हां! एक मानक एल्गोरिदम का प्रयोग करें; फिशर-येट्स गलत होने के लिए बहुत आसान है। –

+3

मैंने हमेशा सोचा है कि इसे 'random_shuffle' क्यों कहा जाता है। इसका अर्थ यह है कि एक 'nonrandom_shuffle' है। एसटीएल के लिए –

+0

+1। सरणी आरए Iterators भी प्रदान करते हैं। Std :: वेक्टर की कोई ज़रूरत नहीं है। – pmr

0

आप कंटेनर का उपयोग कर सकते हैं, मैं सिर्फ 1 से 20

करने के लिए एक std :: संख्या के साथ सेट भर देंगे तो फिर आप अपने सेट से एक यादृच्छिक संख्या खींच और सरणी में डाल सकते हैं।

0

ऐसा कुछ?

int n = 20; //total element of array 
int random = 0, temp=0, start=1; 

for(int i=0; i < n; ++i,++start) 
{ 
    array[i] = start; 
} 

for(int i=0; i<n ; ++i) 
{ 
    random=rand()%(n-i)+i; 
    //swapping, you can make it as a function 
    temp = array[i]; 
    array[i] = array [random]; 
    array[random] = temp; 

} 
0

अन्य संभव तरीके

int array[20]={0}; 
int values[20]; 
for(int i = 0; i < 20; i++) 
    values[i] = i; 
int left = 20; 
for(int i = 0; i < 20; i++) 
{ 
    int n = rand() % left; 
    array[i] = values[n]; 
    left--; 
    values[n] = values[left]; 
} 

पुनश्च Nombers साथ 0 से 19 1 से नहीं 20 से भर दिया।फिशर-येट्स के लिए एक ही

+0

'rand()% left' का उपयोग न करें - उदाहरण के लिए http://members.cox.net/srice1/random/crandom.html – Christoph

0

कोड उदाहरण मूल रूप:

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

void shuffle(int array[], size_t size) 
{ 
    if(size) while(--size) 
    { 
     size_t current = (size_t)(rand()/(1.0 + RAND_MAX) * (size + 1)); 
     int tmp = array[current]; 
     array[current] = array[size]; 
     array[size] = tmp; 
    } 
} 

int main(void) 
{ 
    srand((int)time(NULL)); 
    rand(); // throw away first value: necessary for some implementations 

    int array[] = { 1, 2, 3, 4, 5 }; 
    shuffle(array, sizeof array/sizeof *array); 

    size_t i = 0; 
    for(; i < sizeof array/sizeof *array; ++i) 
     printf("%i\n", array[i]); 

    return 0; 
} 
0

मुझे आशा है कि यह मदद मिलेगी:

#include<algorithm> 
#include<cstdlib> 
#include<iostream> 
#include<iterator> 

int main() 
{ 
    int array[] = {1, 2, 3, 4}; 
    const unsigned SIZE = sizeof(array)/sizeof(int); 

    cout << "Array before: "; 
    std::copy(array, array+SIZE, std::ostream_iterator<int>(cout, ", ")); 

    std::generate(array, array+SIZE, ::rand); // answer for your question 

    cout << "\nArray arter: "; 
    std::copy(array, array+SIZE, std::ostream_iterator<int>(cout, ", ")); 
} 

अगर आप चाहते हैं:

std::generate(array, array + sizeof(array)/sizeof(int), ::rand); 

आप नीचे पूर्ण कोड है इससे कम संख्या के लिए आप ऐसा करने के बाद ऐसा कर सकते हैं:

std::transform(array, array+SIZE, array, std::bind2nd(std::modulus<int>(), 255)); 
संबंधित मुद्दे