1 और 100 के बीच अद्वितीय यादृच्छिक संख्या उत्पन्न करें


99

मैं जावास्क्रिप्ट का उपयोग करके 1 और 100 के बीच कुछ अद्वितीय यादृच्छिक संख्या कैसे उत्पन्न कर सकता हूं ?


19
यह वास्तव में एक जावास्क्रिप्ट नहीं है क्योंकि यह जावास्क्रिप्ट पर ध्यान केंद्रित कर रहा है।
दीवाना हो गया

2
@ अच्छी तरह से जावास्क्रिप्ट में ऐसा करने और किसी अन्य भाषा में करने के बीच कोई आवश्यक अंतर नहीं है, लेकिन मैं बंद करने के लिए मतदान नहीं करूंगा।
पॉइन्टी

1
मैं या तो बंद करने के लिए मतदान नहीं करूंगा। यह पर्याप्त विशिष्ट है।
जोश स्टोडोला


जवाबों:


174

उदाहरण के लिए: 8 अद्वितीय यादृच्छिक संख्याओं को उत्पन्न करने और उन्हें एक सरणी में संग्रहीत करने के लिए, आप बस ऐसा कर सकते हैं:

var arr = [];
while(arr.length < 8){
    var r = Math.floor(Math.random() * 100) + 1;
    if(arr.indexOf(r) === -1) arr.push(r);
}
console.log(arr);


15
वास्तविक कोड स्यूडोकोड की तुलना में इस तरह के सवालों के लिए बहुत बेहतर है;) (मेरे उत्तर को छद्मकोड हटा दिया गया ...)
रोमन स्टार्कोव

3
ओ उठाया जा सकता है; var randomnumber = Math.ceil (Math.random () * 100) का उपयोग करें
Alsciende

9
-1: यह एल्गोरिथ्म भोली दृष्टिकोण है; यह बहुत अक्षम है।
Frerich Raabe

39
वाह। भोला थोड़ा मजबूत मालूम पड़ता है। यह सबसे अच्छा समाधान नहीं हो सकता है, लेकिन यह सरल, संक्षिप्त, देखने में आसान है कि क्या हो रहा है, और जो पूरा करने की आवश्यकता है उसके लिए स्वीकार्य ऑपरेटिंग मापदंडों के भीतर चलता है। अगले कार्य पर। पूर्णता महान है, लेकिन 'किया ’। परफेक्ट’ से बेहतर है।
adam0101

4
एक मौका है कि फ़ंक्शन सरणी में 0 देता है। इस लिंक के अनुसार: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… , Math.random () Returns a random number between 0 (inclusive) and 1 (exclusive)। अगर the Math.random()गलती से 0 वापस आता है, तो Math.ceil(0)0 भी है, हालांकि मौका कम है।
कियान चेन

43
  1. 100 के माध्यम से संख्या 1 के साथ एक सरणी पॉप्युलेट करें।
  2. इसे शफल करें
  3. परिणामी सरणी के पहले 8 तत्वों को लें।

8
निश्चित रूप से यह केवल पहले 8 फेरबदल करने के लिए कोड को ट्विक करने के लिए अधिक कुशल है? (और फिर अर्ध-फेरबदल सरणी के अंतिम 8 तत्वों को लें)
दूसरा

1
यह है कि मैं हमेशा ऐसा कैसे करता हूं। तो अगर मैं एक फ़ाइल से दस यादृच्छिक लाइनें चाहता था जिसमें लाइनों का एक गुच्छा था, तो मैं करता हूं randlines file | head -10
tchrist

1
मुझे लगता है कि यह उचित उत्तर है, क्योंकि यह संभाव्यता विकृति को बनाए रखता है, जो स्वीकार किए गए उत्तर में नहीं है
रोबर्टो टोमैस

2
क्या होगा अगर N = 10 ^ 12? बहुत कुशल नहीं है।
shinzou

2
वास्तविक दुनिया में @shinzou आप जावास्क्रिप्ट का उपयोग करके 10 ^ 12 नंबर को सॉर्ट नहीं करेंगे। एक तुच्छ प्रश्न एक तुच्छ उत्तर के लिए कहता है। मैं यहां दुनिया की भूख को हल करने के लिए नहीं हूं। मैं ऐसा करने के लिए अच्छी तरह से सुसज्जित हूं, लेकिन यह वह नहीं है जो सवाल के बारे में है।
22:egDwight

14

100 नंबरों का क्रमचय उत्पन्न करें और फिर क्रमबद्ध रूप से चुनें।

उपयोग नुथ घसीटना (उर्फ फिशर-येट्स फेरबदल) एल्गोरिथ्म

जावास्क्रिप्ट:

  function fisherYates ( myArray,stop_count ) {
  var i = myArray.length;
  if ( i == 0 ) return false;
  int c = 0;
  while ( --i ) {
     var j = Math.floor( Math.random() * ( i + 1 ) );
     var tempi = myArray[i];
     var tempj = myArray[j];
     myArray[i] = tempj;
     myArray[j] = tempi;

     // Edited thanks to Frerich Raabe
     c++;
     if(c == stop_count)return;

   }
}

लिंक से कोड की गई।

संपादित करें :

बेहतर कोड:

function fisherYates(myArray,nb_picks)
{
    for (i = myArray.length-1; i > 1  ; i--)
    {
        var r = Math.floor(Math.random()*i);
        var t = myArray[i];
        myArray[i] = myArray[r];
        myArray[r] = t;
    }

    return myArray.slice(0,nb_picks);
}

संभावित समस्या:

मान लीजिए कि हमारे पास 100 नंबरों की सरणी है {उदा। [1,2,3 ... 100]} और हम 8 स्वैप के बाद स्वैप करना बंद कर देते हैं; तब अधिकांश बार सरणी {1,2,3,76,5,6,7,8, ... की संख्या की तरह दिखाई देगी, यहां फेरबदल किया जाएगा ... 10}।

क्योंकि हर संख्या को 1/100 तो प्रायिकता के साथ स्वैप किया जाएगा। स्वैपिंग के पहले 8 नंबर 8/100 है जबकि प्रोब। अन्य 92 की अदला-बदली 92/100 है।

लेकिन अगर हम पूर्ण सरणी के लिए एल्गोरिथ्म चलाते हैं तो हमें यकीन है कि (लगभग) हर प्रविष्टि को स्वैप किया जाता है।

अन्यथा हम एक सवाल का सामना करते हैं: कौन से 8 नंबर चुनने के लिए?


5
यह दृष्टिकोण सही है लेकिन उप-अपनाने वाला है: आप आठ स्वैप के बाद फेरबदल करना बंद कर सकते हैं, क्योंकि आपको केवल आठ यादृच्छिक संख्याओं की आवश्यकता है। ऊपर दिया गया कोड संपूर्ण सरणी (इस परिदृश्य में, 100 तत्व) को स्वैप करता है।
फ्रेरिच राबे

कोड को गंभीरता से सुधारा जा सकता था। वापसी मान, साइड इफेक्ट और फ़ंक्शन का उपयोग सभी वास्तव में धुंधले IMO हैं। हो सकता है कि यदि आप अपने फिशरेट्स फ़ंक्शन का उपयोग करते हुए एक समस्या लिखते हैं जो मूल समस्या का सटीक उत्तर देता है, तो यह स्पष्ट होगा।
एलसिंकेड

1
उत्तर बेहतर कोड के साथ अद्यतन किया गया। इसके अलावा, @ फे्रिच रैबे: आठ स्वैप के बाद रुकने की समस्या का उल्लेख किया गया है।
प्रतीक देवघर

आपका फिशर-येट्स एल्गोरिथ्म गलत है। r मैं पर निर्भर होना चाहिए मेरी
awser

ऊफ़ सॉरी मेरी भयानक गलती !! आपका कार्यान्वयन अच्छा है। अच्छा लगा। +1। कृपया मुझे बताएं कि क्या कुछ और गलत है।
प्रतीक देवघर

11

सेट का उपयोग करके आधुनिक जेएस समाधान (और औसत स्थिति ओ (एन))

const nums = new Set();
while(nums.size !== 8) {
  nums.add(Math.floor(Math.random() * 100) + 1);
}

console.log([...nums]);


यह O (n) क्यों है? क्या यह समय की एक मनमानी राशि के लिए लूप नहीं कर सकता है?
एंथनी वाइज़र

@AnthonyWieser आप सही, सबसे खराब स्थिति हैं। मैं औसत केस लगा रहा था क्योंकि सेट.आड ओ (1) है
एलिस्टर

मुझे लगता है कि इसका उपयोग करने से पहले इसका उत्तर 0 की तरह वापस आ सकता थाMath.floor(Math.random()*100) + 1
adam0101

Setजेएस में खोजने के लिए बहुत अच्छा ! हालांकि, यह समाधान तब तक अनावश्यक पीढ़ी की संख्या का कारण नहीं बनेगा जब तक कि एक विशिष्टता की आवश्यकता फिट नहीं होती है, खासकर अंतिम पुनरावृत्तियों में, यदि 8 100 के करीब था? इस प्रकार मुझे लगता है कि मैं sortनीचे के साथ भी सुरुचिपूर्ण जवाब पसंद करता हूं ।
गिलाद बार्नर

10

यदि आप किसी लाइब्रेरी से बचना चाहते हैं, तो उपरोक्त तकनीकें अच्छी हैं, लेकिन अगर आप लाइब्रेरी से ठीक हैं, तो मैं आपको जावास्क्रिप्ट में यादृच्छिक सामान बनाने के लिए संभावना की जाँच करने का सुझाव दूंगा ।

विशेष रूप से अपने प्रश्न को हल करने के लिए, संभावना का उपयोग करना जितना आसान है:

// One line!
var uniques = chance.unique(chance.natural, 8, {min: 1, max: 100});

// Print it out to the document for this snippet so we can see it in action
document.write(JSON.stringify(uniques));
<script src="http://chancejs.com/chance.min.js"></script>

अस्वीकरण, चांस के लेखक के रूप में, मैं थोड़ा पक्षपाती हूं;)


अपवोट क्योंकि मैंने इससे पहले कभी भी रन कोड स्निपेट नहीं देखा था
सर्फ करें

अगर मैं कूपन के लिए एक कोड (8 रैंडम अल्फ़ान्यूमेरिक स्ट्रिंग) बनाना चाहता हूं, जो अद्वितीय होना चाहिए, तो मैं इसे चांस.जेएस के साथ कैसे कर सकता हूं? नोट: कूपन मांग के आधार पर बनाए जाएंगे, इसलिए कोडों की संख्या अनिश्चित होगी
ऑस्कर युंडिनाता

@OscarYuandinata यह आसान है, बस var codes = chance.unique(chance.string, 8)यदि आपको किसी विशेष वर्ण पूल से खींचे गए कोड की आवश्यकता है, तो आप इसे इस तरह निर्दिष्ट कर सकते हैं: chance.unique(chance.string, 8, {pool: "abcd1234"})जहाँ abcd1234 आप पूल में कोई भी वर्ण चाहें। देखें chancejs.com/#string
विक्टर क्विन

@VictorQuinn, माफ करना, मैंने खुद को स्पष्ट नहीं किया। मेरा मतलब है कि कूपन कोड 8 अक्षर यादृच्छिक अल्फ़ान्यूमेरिक स्ट्रिंग होगा, न कि 8 यादृच्छिक अल्फ़ान्यूमेरिक स्ट्रिंग की एक सरणी।
हाहाहा

ओह @OscarYuandinata वह बहुत आसान है chance.string({ length: 8 })और यदि आप केवल कुछ पात्रों को उस तार में प्रदर्शित करना चाहते हैं, chance.string({ pool: 'abcd1234', length: 8 })जो कि abcd1234 के अक्षरों से यादृच्छिक 8 वर्ण स्ट्रिंग लौटाएगा, इसलिए उदाहरण के लिए "2c2c44bc" या "331141cc"
विक्टर क्विन

8

किसी भी लंबे और अविश्वसनीय फेरबदल से बचने के लिए, मैं निम्नलिखित कार्य करूंगा ...

  1. एक सरणी उत्पन्न करें जिसमें क्रम में 1 और 100 के बीच की संख्या हो।
  2. 1 और 100 के बीच एक यादृच्छिक संख्या उत्पन्न करें
  3. इस सूचकांक में संख्या को सरणी में देखें और अपने परिणामों में संग्रहीत करें
  4. एक छोटे से सरणी से एलेमेंट को हटा दें
  5. चरण 2 से दोहराएं, लेकिन यादृच्छिक संख्या की ऊपरी सीमा के रूप में 99 का उपयोग करें
  6. चरण 2 से दोहराएं, लेकिन यादृच्छिक संख्या की ऊपरी सीमा के रूप में 98 का ​​उपयोग करें
  7. चरण 2 से दोहराएं, लेकिन यादृच्छिक संख्या की ऊपरी सीमा के रूप में 97 का उपयोग करें
  8. चरण 2 से दोहराएं, लेकिन यादृच्छिक संख्या की ऊपरी सीमा के रूप में 96 का उपयोग करें
  9. चरण 2 से दोहराएं, लेकिन यादृच्छिक संख्या की ऊपरी सीमा के रूप में 95 का उपयोग करें
  10. चरण 2 से दोहराएँ, लेकिन यादृच्छिक संख्या की ऊपरी सीमा के रूप में 94 का उपयोग करें
  11. चरण 2 से दोहराएं, लेकिन यादृच्छिक संख्या की ऊपरी सीमा के रूप में 93 का उपयोग करें

वोइला - कोई दोहराया संख्या।

अगर कोई दिलचस्पी रखता है तो मैं बाद में कुछ वास्तविक कोड पोस्ट कर सकता हूं।

संपादित करें: यह शायद मुझ में प्रतिस्पर्धात्मक लकीर है, लेकिन @Alsciende द्वारा पोस्ट को देखने के बाद, मैं उस कोड को पोस्ट करने का विरोध नहीं कर सका, जिसका मैंने वादा किया था।

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<title>8 unique random number between 1 and 100</title>
<script type="text/javascript" language="Javascript">
    function pick(n, min, max){
        var values = [], i = max;
        while(i >= min) values.push(i--);
        var results = [];
        var maxIndex = max;
        for(i=1; i <= n; i++){
            maxIndex--;
            var index = Math.floor(maxIndex * Math.random());
            results.push(values[index]);
            values[index] = values[maxIndex];
        }
        return results;
    }
    function go(){
        var running = true;
        do{
            if(!confirm(pick(8, 1, 100).sort(function(a,b){return a - b;}))){
                running = false;
            }
        }while(running)
    }
</script>
</head>

<body>
    <h1>8 unique random number between 1 and 100</h1>
    <p><button onclick="go()">Click me</button> to start generating numbers.</p>
    <p>When the numbers appear, click OK to generate another set, or Cancel to stop.</p>
</body>


लेकिन तब आपका आठवां नंबर 1 से 92 तक यादृच्छिक होता है, 1 से 100 तक नहीं। यदि आपको 90 नंबर चुनना है, तो आपका अंतिम नंबर केवल 1 से 10 तक ही लिया जाएगा, है न?
adam0101

@ adam0101 नहीं, क्योंकि वह संख्या निकालता है क्योंकि वह उन्हें चुनता है। तो चरण 5 में, उसकी सरणी में केवल 99 नंबर हैं। @belugabob आप नथ शफल से अधिक कुशल नहीं हैं। वास्तव में, ब्याह शायद फेरबदल की तुलना में अधिक महंगा है (जो पूरी तरह से विश्वसनीय है)
Alsciende

@ adam0101: वह चुने हुए तत्व को सरणी से हटा रहा है (ऊपर चरण 4 देखें), इस प्रकार यह टालना कि कोई भी तत्व दो बार चुना जाता है। फिर वह अगले यादृच्छिक संख्या के लिए एक निचली ऊपरी सीमा का उपयोग करता है, केवल इसलिए कि सरणी कम है।
फ्रेरिकराबे

@Alsciende, हाँ - सोचा था कि यह अधिक कुशलता से एक फेरबदल का उपयोग करने का एक तरीका होगा, लेकिन पूरी तरह से निश्चित नहीं था। सरणी से आइटम को हटाने से बचने के लिए, बस सरणी से अंतिम प्रविष्टि की प्रतिलिपि बनाएँ (बशर्ते कि यह आपके द्वारा चुनी गई स्थिति नहीं थी) जिसे आपने चुना था।
बेलुगोबोब

1
मानों को कम न करने का कारण। गति, यह है कि इस बात की कोई गारंटी नहीं है कि किसी सरणी की लंबाई को कम करने का कार्य मेमोरी को वास्तविक बनाने के द्वारा नहीं किया जाता है। मैक्सिन्डेक्स का उपयोग करने का एक ही प्रभाव है, केवल सरणी में अंतिम प्रविष्टियों की अनदेखी करके, क्योंकि वे अप्रासंगिक हो जाते हैं।
बेलुगाब

8

एक अन्य तरीका यह है कि आरोही संख्याओं के साथ 100 आइटम सरणी उत्पन्न करें और इसे यादृच्छिक रूप से सॉर्ट करें। यह वास्तव में वास्तव में छोटी और (मेरी राय में) सरल स्निपेट की ओर जाता है।

const numbers = Array(100).fill().map((_, index) => index + 1);
numbers.sort(() => Math.random() - 0.5);
console.log(numbers.slice(0, 8));


यह उन सभी का मेरा पसंदीदा जवाब है। डननो को केवल 6 वोट ही क्यों मिले। सुरुचिपूर्ण और अच्छी जटिलता के साथ (बशर्ते sortइसे अच्छी तरह से लागू किया गया हो, जो मुझे यकीन है कि यह है)।
गिलाद बार्नर

3

मैं यह करूँगा:

function randomInt(min, max) {
    return Math.round(min + Math.random()*(max-min));
}
var index = {}, numbers = [];
for (var i=0; i<8; ++i) {
    var number;
    do {
        number = randomInt(1, 100);
    } while (index.hasOwnProperty("_"+number));
    index["_"+number] = true;
    numbers.push(number);
}
delete index;

3

यह एक बहुत ही सामान्य कार्य है जो मैंने एक सरणी के लिए यादृच्छिक अद्वितीय / गैर-अद्वितीय पूर्णांक बनाने के लिए लिखा है। इस उत्तर के लिए इस परिदृश्य में अंतिम पैरामीटर को सही मान लें।

/* Creates an array of random integers between the range specified 
     len = length of the array you want to generate
     min = min value you require
     max = max value you require
     unique = whether you want unique or not (assume 'true' for this answer)
*/
    function _arrayRandom(len, min, max, unique) {
        var len = (len) ? len : 10,
                min = (min !== undefined) ? min : 1,
                max = (max !== undefined) ? max : 100,
                unique = (unique) ? unique : false,
                toReturn = [], tempObj = {}, i = 0;

        if(unique === true) {
            for(; i < len; i++) {
                var randomInt = Math.floor(Math.random() * ((max - min) + min));
                if(tempObj['key_'+ randomInt] === undefined) {
                    tempObj['key_'+ randomInt] = randomInt;
                    toReturn.push(randomInt);
                } else {
                    i--;
                }
            }
        } else {
            for(; i < len; i++) {
                toReturn.push(Math.floor(Math.random() * ((max - min) + min)));
            }
        }

        return toReturn;
    }

यहाँ 'tempObj' एक बहुत ही उपयोगी obj है क्योंकि उत्पन्न हर यादृच्छिक संख्या सीधे इस tempObj में जाँच करेगी यदि वह कुंजी पहले से मौजूद है, यदि नहीं, तो हम i को एक से कम करते हैं क्योंकि हमें 1 अतिरिक्त रन की आवश्यकता है क्योंकि वर्तमान यादृच्छिक संख्या पहले से मौजूद है ।

अपने मामले में, निम्नलिखित चलाएँ

_arrayRandom(8, 1, 100, true);

बस इतना ही।


यदि मैं 0 को शामिल करना चाहता हूं तो क्या होगा? लाइन min = (min) ? min : 1,हमेशा वापस आएगी 1. (इसलिए 0 का चयन कभी नहीं किया जाएगा)
TBE

एक बहुत अच्छा बिंदु। :)। धन्यवाद, मैंने उचित बदलाव किया है। यदि आप
०.- kaizer1v

2

1 से 100 तक की संख्या को फेरबदल करना सही बुनियादी रणनीति है, लेकिन अगर आपको केवल 8 फेरबदल संख्याओं की आवश्यकता है, तो सभी 100 संख्याओं को फेरबदल करने की कोई आवश्यकता नहीं है।

मैं जावास्क्रिप्ट को बहुत अच्छी तरह से नहीं जानता, लेकिन मेरा मानना ​​है कि जल्दी से 100 नल की एक सरणी बनाना आसान है। फिर, 8 राउंड के लिए, आप 99 + के माध्यम से n + 1 से यादृच्छिक रूप से चयनित तत्व के साथ सरणी का n तत्व (n 0 पर शुरू) स्वैप करते हैं, बेशक, किसी भी तत्व को अभी तक आबादी नहीं हुई है जिसका मतलब है कि तत्व वास्तव में होगा मूल सूचकांक प्लस 1, ताकि कारक में तुच्छ हो। जब आप 8 राउंड के साथ किया जाता है, तो आपके सरणी के पहले 8 तत्वों में आपके 8 फेरबदल नंबर होंगे।


2
var arr = []
while(arr.length < 8){
  var randomnumber=Math.ceil(Math.random()*100)
  if(arr.indexOf(randomnumber) === -1){arr.push(randomnumber)}  
}
document.write(arr);

अन्य उत्तरों की तुलना में कम मैंने देखा है


1

मशीन पर्मर के रूप में एक ही क्रमपरिवर्तन एल्गोरिदम, लेकिन एक प्रोटोटाइप कार्यान्वयन के साथ। बड़ी संख्या में पिक्स के लिए बेहतर अनुकूल। यदि उपलब्ध हो तो js 1.7 विनाशकारी असाइनमेंट का उपयोग करता है।

// swaps elements at index i and j in array this
// swapping is easy on js 1.7 (feature detection)
Array.prototype.swap = (function () {
    var i=0, j=1;
    try { [i,j]=[j,i]; }
    catch (e) {}
    if(i) {
        return function(i,j) {
            [this[i],this[j]] = [this[j],this[i]];
            return this;
        }
    } else {
        return function(i,j) {
            var temp = this[i];
            this[i] = this[j];
            this[j] = temp;
            return this;
        }
    }
})();


// shuffles array this
Array.prototype.shuffle = function() {
    for(var i=this.length; i>1; i--) {
        this.swap(i-1, Math.floor(i*Math.random()));
    }
    return this;
}

// returns n unique random numbers between min and max
function pick(n, min, max) {
    var a = [], i = max;
    while(i >= min) a.push(i--);
    return a.shuffle().slice(0,n);
}

pick(8,1,100);

संपादित करें: बेलुगाब के उत्तर के आधार पर, एक अन्य प्रस्ताव, जो छोटी संख्या में अचार के लिए बेहतर है। विशिष्टता की गारंटी देने के लिए, हम एरे से उठाए गए नंबरों को हटा देते हैं।

// removes n random elements from array this
// and returns them
Array.prototype.pick = function(n) {
    if(!n || !this.length) return [];
    var i = Math.floor(this.length*Math.random());
    return this.splice(i,1).concat(this.pick(n-1));
}

// returns n unique random numbers between min and max
function pick(n, min, max) {
    var a = [], i = max;
    while(i >= min) a.push(i--);
    return a.pick(n);
}

pick(8,1,100);

अच्छा पुनरावर्ती कार्यान्वयन - मैंने अपने जवाब में एक विकल्प पोस्ट किया है, जो ब्याह का उपयोग नहीं करता है, जैसा कि मुझे लगता है कि यह एक परिहार्य प्रदर्शन हिट है (यह नहीं कि ओपी के पास प्रदर्शन के साथ कोई समस्या थी)
belugabob

आपका समाधान चालाक है, लेकिन मैं अपने सरणी # में का उपयोग नहीं करेंगे विधि लेने क्योंकि मैं नहीं चाहता कि यह जब मैं इसे वापस उसके तत्वों के आसपास फेरबदल है।
अलसिंडे

आप किस सरणी में फेरबदल नहीं करना चाहते हैं, मूल 1-100 सरणी या परिणाम? पूर्व को कोई फर्क नहीं पड़ता है, क्योंकि यह एक कार्यशील सरणी है, और बाद की इच्छा, कोड की प्रकृति से, वैसे भी यादृच्छिक क्रम में सामने आती है। बिल्कुल यकीन नहीं है कि मैं आपके कारणों को समझता हूं।
बेलुगाब

मूल एक। मैंने एक सामान्य ऐरे # पिक पद्धति लागू की, जो मुझे उपयोगी लगती है। यह फ़ंक्शन नहीं जानता कि यह कार्यशील सरणी है या नहीं। सामान्य होने के लिए, यह परिवर्तन नहीं करता है इस आवश्यकता से अधिक।
Alsciende

लेकिन यह अभी भी इसे बदल देता है, भले ही केवल थोड़ा, जो इस तकनीक का उपयोग करते समय अपरिहार्य हो।
बेलुगोबोब

1

इस तरह के छेद के साथ सरणियों के लिए [,2,,4,,6,7,,] क्योंकि मेरी समस्या इन छेदों को भरने के लिए थी। इसलिए मैंने अपनी आवश्यकता के अनुसार इसे संशोधित किया :)

निम्नलिखित संशोधित समाधान मेरे लिए काम किया :)

var arr = [,2,,4,,6,7,,]; //example
while(arr.length < 9){
  var randomnumber=Math.floor(Math.random()*9+1);
  var found=false;
  for(var i=0;i<arr.length;i++){
    if(arr[i]==randomnumber){found=true;break;}
  }

  if(!found)
    for(k=0;k<9;k++)
    {if(!arr[k]) //if it's empty  !!MODIFICATION
      {arr[k]=randomnumber; break;}}
}

alert(arr); //outputs on the screen

1

सबसे अच्छा पहले वाला उत्तर इसके द्वारा दिया गया उत्तर है sje397। आपको जितने अच्छे रैंडम नंबर मिलेंगे, उतने जल्दी मिलेंगे।

मेरा समाधान उसके समाधान के समान है। हालांकि, कभी-कभी आप यादृच्छिक क्रम में यादृच्छिक संख्या चाहते हैं, और यही कारण है कि मैंने एक उत्तर पोस्ट करने का फैसला किया है। इसके अलावा, मैं एक सामान्य फ़ंक्शन प्रदान करता हूं।

function selectKOutOfN(k, n) {
  if (k>n) throw "k>n";
  var selection = [];
  var sorted = [];
  for (var i = 0; i < k; i++) {
    var rand = Math.floor(Math.random()*(n - i));
    for (var j = 0; j < i; j++) {
      if (sorted[j]<=rand)
        rand++;
      else
        break;
    }
    selection.push(rand);
    sorted.splice(j, 0, rand);
  }
  return selection;
}

alert(selectKOutOfN(8, 100));

1

यहाँ मेरा ES6 संस्करण है जिसे मैंने एक साथ सिल दिया था। मुझे यकीन है कि यह थोड़ा अधिक समेकित हो सकता है।

function randomArray(i, min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  
  let arr = Array.from({length: i}, () => Math.floor(Math.random()* (max - min)) + min);
  
  return arr.sort();
 }
 
 let uniqueItems = [...new Set(randomArray(8, 0, 100))]
 console.log(uniqueItems);


0

एक हैश टेबल के रूप में ऑब्जेक्ट गुणों का उपयोग करने के बारे में कैसे ? इस तरह आपका सबसे अच्छा परिदृश्य केवल 8 बार यादृच्छिक करना है। यह तभी प्रभावी होगा जब आप संख्याओं का एक छोटा हिस्सा चाहते हैं। यह फिशर-येट्स की तुलना में बहुत कम स्मृति गहन है क्योंकि आपको किसी सरणी के लिए स्थान आवंटित करने की आवश्यकता नहीं है।

var ht={}, i=rands=8;
while ( i>0 || keys(ht).length<rands) ht[Math.ceil(Math.random()*100)]=i--;
alert(keys(ht));

मुझे तब पता चला कि Object.keys (obj) एक ECMAScript 5 फीचर है, इसलिए अभी इनरनेट पर बहुत बेकार है। डर नहीं, क्योंकि मैंने इसे इस तरह से एक कुंजी फ़ंक्शन जोड़कर ECMAScript 3 संगत बनाया।

if (typeof keys == "undefined") 
{ 
  var keys = function(obj) 
  {
    props=[];
    for (k in ht) if (ht.hasOwnProperty(k)) props.push(k);
    return props;
  }
}

0
var bombout=0;
var checkArr=[];
var arr=[];
while(arr.length < 8 && bombout<100){
  bombout++;
  var randomNumber=Math.ceil(Math.random()*100);
  if(typeof checkArr[randomNumber] == "undefined"){
    checkArr[randomNumber]=1;
    arr.push(randomNumber);
  }
}​

// untested - hence bombout

0

यदि आपको और अधिक अद्वितीय चाहिए तो आपको एक सरणी (1..100) उत्पन्न करनी होगी।

var arr=[];
function generateRandoms(){
for(var i=1;i<=100;i++) arr.push(i);
}
function extractUniqueRandom()
{
   if (arr.length==0) generateRandoms();
   var randIndex=Math.floor(arr.length*Math.random());
   var result=arr[randIndex];
   arr.splice(randIndex,1);
   return result;

}
function extractUniqueRandomArray(n)
{
   var resultArr=[];
   for(var i=0;i<n;i++) resultArr.push(extractUniqueRandom());
   return resultArr;
}

उपरोक्त कोड अधिक तेज़ है:
extractUniqueRandomArray (50) => [2, 79, 38, 59, 63, 42, 52, 22, 78, 50, 39, 77, 1, 88, 40, 23, 48, 84, 91 49, 4, 54, 93, 36, 100, 82, 62, 41, 89, 12, 24, 31, 86, 92, 64, 75, 70, 61, 67, 98, 76, 80, 56, 90, 90 83, 44, 43, 47, 7, 53]


0

जावास्क्रिप्ट 1.6 इंडेक्सऑफ फ़ंक्शन के साथ एक ही कोड का दूसरा बेहतर संस्करण (स्वीकृत उत्तर) जोड़ना। हर बार जब आप डुप्लिकेट की जाँच कर रहे हों तो पूरे ऐरो को लूप करने की आवश्यकता नहीं है।

var arr = []
while(arr.length < 8){
  var randomnumber=Math.ceil(Math.random()*100)
  var found=false;
    if(arr.indexOf(randomnumber) > -1){found=true;}
  if(!found)arr[arr.length]=randomnumber;
}

जावास्क्रिप्ट का पुराना संस्करण अभी भी शीर्ष पर संस्करण का उपयोग कर सकता है

पुनश्च: विकी को एक अद्यतन का सुझाव देने की कोशिश की गई लेकिन इसे अस्वीकार कर दिया गया। मुझे अभी भी लगता है कि यह दूसरों के लिए उपयोगी हो सकता है।


0

यह मेरा व्यक्तिगत समाधान है:

<script>

var i, k;
var numbers = new Array();
k = Math.floor((Math.random()*8));
numbers[0]=k;
    for (var j=1;j<8;j++){
        k = Math.floor((Math.random()*8));
i=0;
while (i < numbers.length){
if (numbers[i] == k){
    k = Math.floor((Math.random()*8));
    i=0;
}else {i++;}
}
numbers[j]=k;
    }
    for (var j=0;j<8;j++){
alert (numbers[j]);
    }
</script>

यह यादृच्छिक रूप से 8 अद्वितीय सरणी मान (0 और 7 के बीच) उत्पन्न करता है, फिर एक अलर्ट बॉक्स का उपयोग करके उन्हें प्रदर्शित करता है।


0
function getUniqueRandomNos() {
    var indexedArrayOfRandomNo = [];
    for (var i = 0; i < 100; i++) {
        var randNo = Math.random();
        indexedArrayOfRandomNo.push([i, randNo]);
    }
    indexedArrayOfRandomNo.sort(function (arr1, arr2) {
        return arr1[1] - arr2[1]
    });
    var uniqueRandNoArray = [];
    for (i = 0; i < 8; i++) {
        uniqueRandNoArray.push(indexedArrayOfRandomNo[i][0]);
    }
    return uniqueRandNoArray;
}

मुझे लगता है कि यह विधि अधिकांश उत्तरों में दी गई विधियों से भिन्न है, इसलिए मैंने सोचा कि मैं यहां एक उत्तर जोड़ सकता हूं (हालांकि प्रश्न 4 साल पहले पूछा गया था)।

हम 100 यादृच्छिक संख्याएँ उत्पन्न करते हैं, और उनमें से प्रत्येक को 1 से 100 तक की संख्याओं के साथ टैग करते हैं। फिर हम इन टैग किए गए यादृच्छिक नंबरों को क्रमबद्ध करते हैं, और टैग बेतरतीब ढंग से बदल जाते हैं। वैकल्पिक रूप से, इस प्रश्न में आवश्यकतानुसार, कोई टैग किए गए यादृच्छिक संख्याओं के शीर्ष 8 को खोजने के साथ दूर कर सकता है। शीर्ष 8 आइटम ढूँढना पूरे सरणी को छाँटने से सस्ता है।

यहां ध्यान देना चाहिए, कि छंटाई एल्गोरिथ्म इस एल्गोरिथ्म को प्रभावित करता है। यदि उपयोग किया गया छँटाई एल्गोरिथ्म स्थिर है, तो छोटी संख्या के पक्ष में थोड़ा पूर्वाग्रह है। आदर्श रूप से, हम चाहते हैं कि छँटाई एल्गोरिथ्म अस्थिर हो और स्थिरता (या अस्थिरता) के प्रति पूरी तरह से समान संभावना वितरण के साथ उत्तर देने के लिए भी पक्षपाती न हो।


0

यह 20 अंक तक की यादृच्छिक संख्या को उत्पन्न करने से निपट सकता है

जे एस

 var generatedNumbers = [];

    function generateRandomNumber(precision) { // input --> number precision in integer 
        if (precision <= 20) {
            var randomNum = Math.round(Math.random().toFixed(precision) * Math.pow(10, precision));
            if (generatedNumbers.indexOf(randomNum) > -1) {
                if (generatedNumbers.length == Math.pow(10, precision))
                    return "Generated all values with this precision";
                    return generateRandomNumber(precision);
            } else {
                generatedNumbers.push(randomNum);
                return randomNum;
            }
        } else
           return "Number Precision shoould not exceed 20";
    }
    generateRandomNumber(1);

यहां छवि विवरण दर्ज करें

jsFiddle


0

यह समाधान हैश का उपयोग करता है जो कि सरणी में रहता है, तो जाँच करने की तुलना में अधिक प्रदर्शन करने वाला ओ (1) है। इसकी अतिरिक्त सुरक्षित जाँच भी है। आशा करता हूँ की ये काम करेगा।

function uniqueArray(minRange, maxRange, arrayLength) {
  var arrayLength = (arrayLength) ? arrayLength : 10
  var minRange = (minRange !== undefined) ? minRange : 1
  var maxRange = (maxRange !== undefined) ? maxRange : 100
  var numberOfItemsInArray = 0
  var hash = {}
  var array = []

  if ( arrayLength > (maxRange - minRange) ) throw new Error('Cannot generate unique array: Array length too high')

  while(numberOfItemsInArray < arrayLength){
    // var randomNumber = Math.floor(Math.random() * (maxRange - minRange + 1) + minRange)
    // following line used for performance benefits
    var randomNumber = (Math.random() * (maxRange - minRange + 1) + minRange) << 0

    if (!hash[randomNumber]) {
      hash[randomNumber] = true
      array.push(randomNumber)
      numberOfItemsInArray++
    }
  }
  return array
}
document.write(uniqueArray(1, 100, 8))

0

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

यह sampleफ़ंक्शन आलसी तरीके से काम करता है, जो आपको मांगने वाले आइटमों के प्रति पुनरावृत्ति के लिए 1 यादृच्छिक आइटम Nदेता है। यह अच्छा है क्योंकि यदि आप 1000 की सूची से केवल 3 आइटम चाहते हैं , तो आपको पहले सभी 1000 आइटमों को स्पर्श करने की आवश्यकता नहीं है।

// sample :: Integer -> [a] -> [a]
const sample = n => function* (xs) {
  let ys = xs.slice(0);
  let len = xs.length;
  while (n > 0 && len > 0) {
    let i = (Math.random() * len) >> 0;
    yield ys.splice(i,1)[0];
    n--; len--;
  }
}

// example inputs
let items = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
let numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

// get 3 random items
for (let i of sample(3) (items))
  console.log(i); // f g c

// partial application
const lotto = sample(3);
for (let i of lotto(numbers))
  console.log(i); // 3 8 7

// shuffle an array
const shuffle = xs => Array.from(sample (Infinity) (xs))
console.log(shuffle(items)) // [b c g f d e a]

मैंने sampleऐसे तरीके से लागू करने का विकल्प चुना जो इनपुट सरणी को म्यूट नहीं करता है, लेकिन आप आसानी से यह तर्क दे सकते हैं कि परिवर्तनशील कार्यान्वयन अनुकूल है।

उदाहरण के लिए, shuffleफ़ंक्शन मूल इनपुट सरणी को म्यूट करना चाह सकता है। या आप हर बार इनपुट को अपडेट करते हुए एक ही इनपुट से कई बार नमूना लेना चाह सकते हैं।

// sample :: Integer -> [a] -> [a]
const sample = n => function* (xs) {
  let len = xs.length;
  while (n > 0 && len > 0) {
    let i = (Math.random() * len) >> 0;
    yield xs.splice(i,1)[0];
    n--; len--;
  }
}

// deal :: [Card] -> [Card]
const deal = xs => Array.from(sample (2) (xs));

// setup a deck of cards (13 in this case)
// cards :: [Card]
let cards = 'A234567890JQK'.split('');

// deal 6 players 2 cards each
// players :: [[Card]]
let players = Array.from(Array(6), $=> deal(cards))

console.log(players);
// [K, J], [6, 0], [2, 8], [Q, 7], [5, 4], [9, A]

// `cards` has been mutated. only 1 card remains in the deck
console.log(cards);
// [3]

sampleसरणी इनपुट उत्परिवर्तन के कारण अब शुद्ध कार्य नहीं है , लेकिन कुछ परिस्थितियों में (ऊपर प्रदर्शित) यह अधिक समझ में आ सकता है।


एक और कारण मैंने एक फ़ंक्शन के बजाय एक जनरेटर चुना जो सिर्फ एक सरणी देता है क्योंकि आप कुछ विशिष्ट स्थिति तक नमूना जारी रखना चाह सकते हैं।

शायद मैं 1,000,000 यादृच्छिक संख्याओं की सूची से पहला अभाज्य अंक चाहता हूं।

  • "मुझे कितने नमूने चाहिए?" - आपको निर्दिष्ट करने की आवश्यकता नहीं है
  • "क्या मुझे पहले सभी अपराधों को खोजना होगा और फिर एक यादृच्छिक प्रधानमंत्री का चयन करना होगा?" - नहीं।

क्योंकि हम एक जनरेटर के साथ काम कर रहे हैं, यह कार्य तुच्छ है

const randomPrimeNumber = listOfNumbers => {
  for (let x of sample(Infinity) (listOfNumbers)) {
    if (isPrime(x))
      return x;
  }
  return NaN;
}

यह एक समय में लगातार 1 यादृच्छिक संख्या का नमूना लेगा, xयह जांचें कि क्या यह प्रमुख है, तो xयदि यह है तो वापस लौटें । यदि कोई प्राइम पाए जाने से पहले संख्याओं की सूची समाप्त हो जाती है, NaNतो वापस कर दी जाती है।


ध्यान दें:

यह उत्तर मूल रूप से एक और प्रश्न पर साझा किया गया था जिसे इस एक के डुप्लिकेट के रूप में बंद कर दिया गया था। क्योंकि यह यहां प्रदान किए गए अन्य समाधानों से बहुत अलग है, मैंने इसे यहां भी साझा करने का निर्णय लिया है


0
getRandom (min, max) {
  return Math.floor(Math.random() * (max - min)) + min
}

getNRandom (min, max, n) {
  const numbers = []
  if (min > max) {
    return new Error('Max is gt min')
  }

  if (min === max) {
    return [min]
  }

  if ((max - min) >= n) {
    while (numbers.length < n) {
      let rand = this.getRandom(min, max + 1)
      if (numbers.indexOf(rand) === -1) {
        numbers.push(rand)
      }
    }
  }

  if ((max - min) < n) {
    for (let i = min; i <= max; i++) {
      numbers.push(i)
    }
  }
  return numbers
}

0

A का उपयोग करना Setआपका सबसे तेज विकल्प है। यहां एक अद्वितीय यादृच्छिक प्राप्त करने के लिए एक सामान्य कार्य है जो कॉलबैक जनरेटर का उपयोग करता है। अब यह तेज और पुन: प्रयोज्य है

// Get a unique 'anything'
let unique = new Set()

function getUnique(generator) {
  let number = generator()
  while (!unique.add(number)) {
    number = generator()
  }
  return number;
}

// The generator.  Return anything, not just numbers.
const between_1_100 = () => 1 + Math.floor(Math.random() * 100)

// Test it
for (var i = 0; i < 8; i++) {
  const aNumber = getUnique(between_1_100)
}
// Dump the 'stored numbers'
console.log(Array.from(unique))


0

यह फिशर येट्स / डर्स्टनफेल्ड शफल का कार्यान्वयन है , लेकिन एक सरणी के वास्तविक निर्माण के बिना इस प्रकार अंतरिक्ष जटिलता या स्मृति को कम करने की आवश्यकता होती है, जब उपलब्ध तत्वों की संख्या की तुलना में पिक आकार छोटा होता है।

100 से 8 नंबर लेने के लिए, 100 तत्वों की एक सरणी बनाना आवश्यक नहीं है।

मान लिया जाता है कि एक सरणी बनाई गई है,

  • सरणी (100) के अंत से, rnd1 से 100 तक यादृच्छिक संख्या ( ) प्राप्त करें
  • 100 स्वैप और यादृच्छिक संख्या rnd
  • चरण 1 को सरणी (99) के साथ दोहराएं

यदि कोई सरणी नहीं बनाई गई है, तो वास्तविक स्वैप किए गए पदों को याद रखने के लिए ए हैशपॉप का उपयोग किया जा सकता है। जब उत्पन्न दूसरी यादृच्छिक संख्या पहले से उत्पन्न संख्याओं में से एक के बराबर होती है, तो मानचित्र वास्तविक मूल्य के बजाय उस स्थिति में वर्तमान मूल्य प्रदान करता है।

const getRandom_ = (start, end) => {
  return Math.floor(Math.random() * (end - start + 1)) + start;
};
const getRealValue_ = (map, rnd) => {
  if (map.has(rnd)) {
    return getRealValue_(map, map.get(rnd));
  } else {
    return rnd;
  }
};
const getRandomNumbers = (n, start, end) => {
  const out = new Map();
  while (n--) {
    const rnd = getRandom_(start, end--);
    out.set(getRealValue_(out, rnd), end + 1);
  }
  return [...out.keys()];
};

console.info(getRandomNumbers(8, 1, 100));
console.info(getRandomNumbers(8, 1, Math.pow(10, 12)));
console.info(getRandomNumbers(800000, 1, Math.pow(10, 15)));


0

यहाँ 0 से 100 की सीमा (0 और 100 दोनों शामिल) से बिना किसी दोहराव के लिए लिए गए यादृच्छिक 5 नंबरों का एक उदाहरण है।

let finals = [];
const count = 5; // Considering 5 numbers
const max = 100;

for(let i = 0; i < max; i++){
  const rand = Math.round(Math.random() * max);
  !finals.includes(rand) && finals.push(rand)
}

finals = finals.slice(0, count)

-1

आप इसे इस तरह से एक लाइनर के साथ भी कर सकते हैं:

[...((add, set) => add(set, add))((set, add) => set.size < 8 ? add(set.add(Math.floor(Math.random()*100) + 1), add) : set, new Set())]


कुछ भी असाइन नहीं करने की शुद्धता के लिए।
Marcin Król
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.