Bir diziden rastgele eleman sayısı nasıl elde edilir?


103

'JavaScript'teki bir diziden öğelere rastgele nasıl erişilir' üzerinde çalışıyorum. Bununla ilgili birçok bağlantı buldum. Gibi: JavaScript dizisinden rastgele öğe alın

var item = items[Math.floor(Math.random()*items.length)];

Ancak bunda diziden sadece bir öğe seçebiliriz. Birden fazla unsur istiyorsak, bunu nasıl başarabiliriz? Bir diziden birden fazla elemanı nasıl elde edebiliriz?


5
Birden çok kez mi çalıştırıyorsunuz?
Bergi

2
Bu ifadeden bunu yapabilir miyiz? Yinelenenleri üreten döngü.
Shyam Dixit

1
Bu tam ifadeden birden fazla öğe elde edemezsiniz.
Sébastien


1
Buradaki bazı çözümleri test etmek için bir JsPerf yaptım. @ Bergi genel olarak en iyisi gibi görünüyor, oysa benimki diziden birçok öğeye ihtiyacınız varsa daha iyi çalışıyor. jsperf.com/k-random-elements-from-array
Tibos

Yanıtlar:


97

Bu tahribatsız (ve hızlı ) işlevi deneyin :

function getRandom(arr, n) {
    var result = new Array(n),
        len = arr.length,
        taken = new Array(len);
    if (n > len)
        throw new RangeError("getRandom: more elements taken than available");
    while (n--) {
        var x = Math.floor(Math.random() * len);
        result[n] = arr[x in taken ? taken[x] : x];
        taken[x] = --len in taken ? taken[len] : len;
    }
    return result;
}

10
Hey adamım, sadece bu algoritmanın güzelliğini takdir etmek için yaklaşık on dakika harcadığımı söylemek istedim.
Prajeeth Emanuel


@Derek 朕 會 功夫 Ah, zekice, bu gerçekten büyük aralıklardan küçük örnekler için çok daha iyi çalışıyor. Özellikle bir ES6 kullanırken Set('13: - / 'de mevcut değildi)
Bergi

@AlexWhite Geri bildiriminiz için teşekkürler, bu hatanın yıllarca herkesten kaçtığına inanamıyorum. Sabit. Yine de bir yorum göndermiş olmalısın, bir düzenleme önermemelisin.
Bergi

2
@ cbdev420 Evet, bu sadece (kısmi) bir fisher-yates karışıklığı
Bergi

189

Sadece iki satır:

// Shuffle array
const shuffled = array.sort(() => 0.5 - Math.random());

// Get sub-array of first n elements after shuffled
let selected = shuffled.slice(0, n);

DEMO :


22
Çok hoş! Elbette bir let random = array.sort(() => .5 - Math.random()).slice(0,n)
hat

1
Dahi! Yerleşik işlevselliği kullanarak zarif, kısa ve basit, hızlı.
Vlad

35
Güzel, ama rastgele olmaktan uzak. İlk öğenin, sonuncusundan çok daha fazla seçilme şansı vardır. Nedenini burada görün: stackoverflow.com/a/18650169/1325646
pomber

Bu, orijinal dizinin
türünü korumaz

3
İnanılmaz! diziyi olduğu gibi tutmak istiyorsanız, ilk satırı şu şekilde değiştirebilirsiniz: const shuffled = [... dizi] .sort (() => 0.5 - Math.random ());
Yair Levy


12

.samplePython standart kitaplığından taşıma :

function sample(population, k){
    /*
        Chooses k unique random elements from a population sequence or set.

        Returns a new list containing elements from the population while
        leaving the original population unchanged.  The resulting list is
        in selection order so that all sub-slices will also be valid random
        samples.  This allows raffle winners (the sample) to be partitioned
        into grand prize and second place winners (the subslices).

        Members of the population need not be hashable or unique.  If the
        population contains repeats, then each occurrence is a possible
        selection in the sample.

        To choose a sample in a range of integers, use range as an argument.
        This is especially fast and space efficient for sampling from a
        large population:   sample(range(10000000), 60)

        Sampling without replacement entails tracking either potential
        selections (the pool) in a list or previous selections in a set.

        When the number of selections is small compared to the
        population, then tracking selections is efficient, requiring
        only a small set and an occasional reselection.  For
        a larger number of selections, the pool tracking method is
        preferred since the list takes less space than the
        set and it doesn't suffer from frequent reselections.
    */

    if(!Array.isArray(population))
        throw new TypeError("Population must be an array.");
    var n = population.length;
    if(k < 0 || k > n)
        throw new RangeError("Sample larger than population or is negative");

    var result = new Array(k);
    var setsize = 21;   // size of a small set minus size of an empty list

    if(k > 5)
        setsize += Math.pow(4, Math.ceil(Math.log(k * 3, 4)))

    if(n <= setsize){
        // An n-length list is smaller than a k-length set
        var pool = population.slice();
        for(var i = 0; i < k; i++){          // invariant:  non-selected at [0,n-i)
            var j = Math.random() * (n - i) | 0;
            result[i] = pool[j];
            pool[j] = pool[n - i - 1];       // move non-selected item into vacancy
        }
    }else{
        var selected = new Set();
        for(var i = 0; i < k; i++){
            var j = Math.random() * n | 0;
            while(selected.has(j)){
                j = Math.random() * n | 0;
            }
            selected.add(j);
            result[i] = population[j];
        }
    }

    return result;
}

Uygulama Lib / random.py'den alınmıştır .

Notlar:

  • setsizeverimlilik için Python'daki özelliklere göre belirlenir. JavaScript için ayarlanmamasına rağmen, algoritma beklendiği gibi çalışmaya devam edecektir.
  • Bu sayfada açıklanan diğer bazı cevaplar, yanlış kullanımdan dolayı ECMAScript şartnamesine göre güvenli değildir Array.prototype.sort. Ancak bu algoritmanın sınırlı bir sürede sona ereceği garanti edilir.
  • SetUygulanmamış eski tarayıcılar için , set bir Arrayile .has(j)değiştirilebilir ve ile değiştirilebilir .indexOf(j) > -1.

Kabul edilen cevaba karşı performans:


Aşağıda bu kodun optimize edilmiş bir sürümünü yayınladım . Ayrıca gönderinizdeki ikinci algo'daki yanlış rastgele parametre düzeltildi. Önceki önyargılı sürümü üretimde kaç kişinin kullandığını merak ediyorum, kritik bir şey ummuyorum.
kullanıcı

11

Orijinal diziyi değiştirmeden 5 rastgele öğe elde etmek:

const n = 5;
const sample = items
  .map(x => ({ x, r: Math.random() }))
  .sort((a, b) => a.r - b.r)
  .map(a => a.x)
  .slice(0, n);

(Bunu büyük listeler için kullanmayın)


Bunun nasıl çalıştığına dair daha iyi bir açıklama yapabilir miyiz?
Kasım

10

bunu yapan bir işlev oluşturun:

var getMeRandomElements = function(sourceArray, neededElements) {
    var result = [];
    for (var i = 0; i < neededElements; i++) {
        result.push(sourceArray[Math.floor(Math.random()*sourceArray.length)]);
    }
    return result;
}

Ayrıca sourceArray'de döndürülecek kadar eleman olup olmadığını kontrol etmelisiniz. ve benzersiz öğelerin döndürülmesini istiyorsanız, seçili öğeyi sourceArray'den kaldırmalısınız.


İyi cevap! Cevabıma bir göz atın, kodunuzu kopyalayın ve "yalnızca benzersiz öğeler" işlevselliği ekleyin.
evilReiko

1
Bu işlev aynı öğeyi sourceArraybirden çok kez döndürebilir .
Sampo

6

ES6 sözdizimi

const pickRandom = (arr,count) => {
  let _arr = [...arr];
  return[...Array(count)].map( ()=> _arr.splice(Math.floor(Math.random() * _arr.length), 1)[0] ); 
}

4

Tekrarlar olmadan bir döngüdeki dizideki öğeleri rastgele almak istiyorsanız, seçili öğeyi diziden şu şekilde kaldırabilirsiniz splice:

var items = [1, 2, 3, 4, 5];
var newItems = [];

for (var i = 0; i < 3; i++) {
  var idx = Math.floor(Math.random() * items.length);
  newItems.push(items[idx]);
  items.splice(idx, 1);
}

console.log(newItems);


1
İtems.splice (idx, 1) ifadesinde neden bu '1'i kullanıyorsunuz? ekleme ??
Shyam Dixit

2
Shyam Dixit , uygun MDN belgeleri1 olup deleteCountkaldırmak için eski dizi elemanlarının sayısını işaret etmektedir. (Bu arada, son iki satırı 'ya indirdim newItems.push(items.splice(idx, 1)[0])).
Kurt Peek

2
Array.prototype.getnkill = function() {
    var a = Math.floor(Math.random()*this.length);
    var dead = this[a];
    this.splice(a,1);
    return dead;
}

//.getnkill() removes element in the array 
//so if you like you can keep a copy of the array first:

//var original= items.slice(0); 


var item = items.getnkill();

var anotheritem = items.getnkill();

2

İşte güzel yazılmış bir versiyon. Başarısız olmaz. Örnek boyutu orijinal dizinin uzunluğundan büyükse karıştırılmış bir dizi döndürür.

function sampleArr<T>(arr: T[], size: number): T[] {
  const setOfIndexes = new Set<number>();
  while (setOfIndexes.size < size && setOfIndexes.size < arr.length) {
    setOfIndexes.add(randomIntFromInterval(0, arr.length - 1));
  }
  return Array.from(setOfIndexes.values()).map(i => arr[i]);
}

const randomIntFromInterval = (min: number, max: number): number =>
  Math.floor(Math.random() * (max - min + 1) + min);

2

lodash ( https://lodash.com/ ) _.sampleve _.sampleSize.

Koleksiyondan koleksiyonun boyutuna kadar benzersiz anahtarlarda bir veya n rastgele öğe alır.

_.sample([1, 2, 3, 4]);
// => 2

_.sampleSize([1, 2, 3], 2);
// => [3, 1]
 
_.sampleSize([1, 2, 3], 4);
// => [2, 3, 1]

Nedir _? Standart bir Javascript nesnesi değil.
vanowm

Merhaba @vanowm, bu lodash lodash.com
nodejh

1

DÜZENLEME : Yalnızca birkaç öğe elde etmek istiyorsanız, bu çözüm burada sunulanlardan (kaynak diziyi birleştiren) daha yavaştır. Bu çözümün hızı, yalnızca orijinal dizideki öğelerin sayısına bağlıyken, ekleme çözümünün hızı, çıktı dizisinde gereken öğelerin sayısına bağlıdır.

Yinelenmeyen rastgele öğeler istiyorsanız, dizinizi karıştırıp yalnızca istediğiniz kadar alabilirsiniz:

function shuffle(array) {
    var counter = array.length, temp, index;

    // While there are elements in the array
    while (counter--) {
        // Pick a random index
        index = (Math.random() * counter) | 0;

        // And swap the last element with it
        temp = array[counter];
        array[counter] = array[index];
        array[index] = temp;
    }

    return array;
}

var arr = [0,1,2,3,4,5,7,8,9];

var randoms = shuffle(arr.slice(0)); // array is cloned so it won't be destroyed
randoms.length = 4; // get 4 random elements

DEMO: http://jsbin.com/UHUHuqi/1/edit

Buradan alınan karıştırma işlevi: https://stackoverflow.com/a/6274398/1669279


Bu, diziden gerekli olan rastgele öğelerin yüzdesine bağlıdır. 10 elemanlı bir diziden 9 rastgele eleman istiyorsanız, rastgele 9 elemanı arka arkaya çıkarmaktan kesinlikle daha hızlı olacaktır. Bunun yararlı olduğu yüzde% 50'den azsa, bu çözümün en hızlı olduğu kullanım durumları vardır. Aksi takdirde faydasız olduğunu kabul ediyorum :).
Tibos

9 öğeyi karıştırmanın, 10 öğeyi karıştırmaktan daha hızlı olduğunu söyledim. Btw OP'nin girdi dizisini yok etmek istemediğinden eminim…
Bergi

9 elementi karıştırmanın bu soruna nasıl yardımcı olduğunu anladığımı sanmıyorum. Dizinin yarısından fazlasını istiyorsanız, rasgele öğeleri istediğiniz kadar kalana kadar basitçe dilimleyebileceğinizi ve ardından rastgele bir sıra elde etmek için karıştırabileceğinizi biliyorum. Kaçırdığım bir şey var mı? Not: Sabit dizi yıkımı, teşekkürler.
Tibos

"Yarısı" ile hiçbir şey yapmak zorunda değil. Sadece geri almak istediğiniz öğeler kadar iş yapmanız gerekir, hiçbir noktada tüm diziyi işlemeniz gerekmez. Mevcut kodunuzun karmaşıklığı var O(n+k)(dizide n öğe, bunlardan k'sini istiyorsunuz) ancak O(k)mümkün (ve optimal).
Bergi

1
Tamam, kodunuz, döngüyü değiştirip son (ilk yerine) öğeleri O(2n)ondan O(n+k)çıkarırsanız indirgenebilecek daha fazla benzerliğe sahiptir . Indeed'de yok , ancak bir çözüm hala mümkün (cevabıma bakın). Ancak uzay karmaşıklığı maalesef aynı kalır , ancak seyrek dizi uygulamasına bağlı olabilir . while (counter-- > len-k)ksplice(i, 1)O(1)O(k)O(n+k)O(2k)
Bergi

1

Bu tür bir sorunu çözmek için bir işleve ihtiyacım vardı, bu yüzden burada paylaşıyorum.

    const getRandomItem = function(arr) {
        return arr[Math.floor(Math.random() * arr.length)];
    }

    // original array
    let arr = [4, 3, 1, 6, 9, 8, 5];

    // number of random elements to get from arr
    let n = 4;

    let count = 0;
    // new array to push random item in
    let randomItems = []
    do {
        let item = getRandomItem(arr);
        randomItems.push(item);
        // update the original array and remove the recently pushed item
        arr.splice(arr.indexOf(item), 1);
        count++;
    } while(count < n);

    console.log(randomItems);
    console.log(arr);

Not: Eğer n = arr.lengthtemelde diziyi karıştırırsanız arrve randomItemskarıştırılmış diziyi döndürürseniz.

Demo


1

Bu cevapta, tüm elemanların rastgele alt diziye sahip olması için eşit şans veren en iyi yöntemi bilmem gereken testi sizinle paylaşmak istiyorum.

Yöntem 01

array.sort(() => Math.random() - Math.random()).slice(0, n)

Bu yöntemi kullanarak, bazı unsurların diğerlerine kıyasla daha yüksek şansı vardır.

calculateProbability = function(number=0 ,iterations=10000,arraySize=100) { 
let occ = 0 
for (let index = 0; index < iterations; index++) {
   const myArray= Array.from(Array(arraySize).keys()) //=> [0, 1, 2, 3, 4, ... arraySize]
   
  /** Wrong Method */
    const arr = myArray.sort(function() {
     return val= .5 - Math.random();
      });
     
  if(arr[0]===number) {
    occ ++
    }

    
}

console.log("Probability of ",number, " = ",occ*100 /iterations,"%")

}

calculateProbability(0)
calculateProbability(0)
calculateProbability(0)
calculateProbability(50)
calculateProbability(50)
calculateProbability(50)
calculateProbability(25)
calculateProbability(25)
calculateProbability(25)

Yöntem 2

Bu yöntemi kullanarak, öğeler aynı olasılığa sahiptir:

 const arr = myArray
      .map((a) => ({sort: Math.random(), value: a}))
      .sort((a, b) => a.sort - b.sort)
      .map((a) => a.value)

calculateProbability = function(number=0 ,iterations=10000,arraySize=100) { 
let occ = 0 
for (let index = 0; index < iterations; index++) {
   const myArray= Array.from(Array(arraySize).keys()) //=> [0, 1, 2, 3, 4, ... arraySize]
   

  /** Correct Method */
  const arr = myArray
  .map((a) => ({sort: Math.random(), value: a}))
  .sort((a, b) => a.sort - b.sort)
  .map((a) => a.value)
    
  if(arr[0]===number) {
    occ ++
    }

    
}

console.log("Probability of ",number, " = ",occ*100 /iterations,"%")

}

calculateProbability(0)
calculateProbability(0)
calculateProbability(0)
calculateProbability(50)
calculateProbability(50)
calculateProbability(50)
calculateProbability(25)
calculateProbability(25)
calculateProbability(25)

Doğru cevap aşağıdaki bağlantıda yayınlanmıştır: https://stackoverflow.com/a/46545530/3811640


1

İşte Python'dan @Derek tarafından taşınan kodun optimize edilmiş bir sürümü , eklenmiş yıkıcı (yerinde) seçenekle birlikte gidebilirseniz mümkün olan en hızlı algoritma olmasını sağlar. Aksi takdirde ya tam bir kopya oluşturur ya da büyük bir diziden istenen az sayıda öğe için seçim tabanlı bir algoritmaya geçer.

// Chooses k unique random elements from pool.
function sample(pool, k, destructive) {
    var n = pool.length;

    if (k < 0 || k > n)
        throw new RangeError("Sample larger than population or is negative");

    if (destructive || n <= (k <= 5 ? 21 : 21 + Math.pow(4, Math.ceil(Math.log(k*3, 4))))) {
        if (!destructive)
            pool = Array.prototype.slice.call(pool);
        for (var i = 0; i < k; i++) { // invariant: non-selected at [i,n)
            var j = i + Math.random() * (n - i) | 0;
            var x = pool[i];
            pool[i] = pool[j];
            pool[j] = x;
        }
        pool.length = k; // truncate
        return pool;
    } else {
        var selected = new Set();
        while (selected.add(Math.random() * n | 0).size < k) {}
        return Array.prototype.map.call(selected, i => population[i]);
    }
}

Derek'in uygulamasına kıyasla, ilk algoritma Firefox'ta çok daha hızlı, Chrome'da biraz daha yavaş, ancak şimdi yıkıcı seçeneğe sahip - en performanslı olanı. İkinci algoritma sadece% 5-15 daha hızlıdır. K ve n'ye bağlı olarak değiştikleri ve muhtemelen yeni tarayıcı sürümleriyle gelecekte bir şey ifade etmeyecekleri için somut sayılar vermemeye çalışıyorum.

Algoritmalar arasında seçim yapan sezgisel yöntem, Python kodundan kaynaklanır. Bazen daha yavaş olanı seçmesine rağmen, olduğu gibi bıraktım. JS için optimize edilmelidir, ancak köşe kasaların performansı tarayıcıya ve sürümlerine bağlı olduğundan karmaşık bir görevdir. Örneğin 1000 veya 1050 üzerinden 20'yi seçmeye çalıştığınızda, buna göre birinci veya ikinci algoritmaya geçecektir. Bu durumda, ilki Chrome 80'de ikinciden 2 kat daha hızlı, Firefox 74'te ise 3 kat daha yavaş çalışır.


log(k*3, 4)JS'nin baseargümanı olmadığı için bir hata var . Olmalılog(k*3)/log(4)
disfated

Ayrıca, .txt poololarak yeniden kullandığınız kısımda bir dezavantaj görüyorum result. Kısalttığınız pooliçin, artık örnekleme için bir kaynak olarak kullanılamaz ve bir dahaki sefere kullandığınızda bir kaynaktan yeniden sampleoluşturmak zorunda kalacaksınız pool. Derek'in uygulaması yalnızca havuzu karıştırır, böylece yeniden oluşturmadan örnekleme için mükemmel şekilde yeniden kullanılabilir. Ve bunun en sık kullanılan durum olduğuna inanıyorum.
44'te reddedildi

1

2020
yıkıcı olmayan işlevsel programlama stili, değişmez bir bağlamda çalışıyor.

const _randomslice = (ar, size) => {
  let new_ar = [...ar];
  new_ar.splice(Math.floor(Math.random()*ar.length),1);
  return ar.length <= (size+1) ? new_ar : _randomslice(new_ar, size);
}


console.log(_randomslice([1,2,3,4,5],2));


Fonksiyonun bir kaynak diziden tüm olası rastgele dizileri oluşturmadığının farkındayım. Diğer dünyada, sonuç olması gerektiği kadar rastgele değil ... herhangi bir iyileştirme fikri?
MAMY Sébastien

_shufflefonksiyon nerede ?
vanowm

0

Yeterli olduğunda srcArray'den rastgele öğeleri tek tek çıkarır veya srcArray'de ayıklanacak başka öğe kalmaz. Hızlı ve güvenilir.

function getNRandomValuesFromArray(srcArr, n) {
    // making copy to do not affect original srcArray
    srcArr = srcArr.slice();
    resultArr = [];
    // while srcArray isn't empty AND we didn't enough random elements
    while (srcArr.length && resultArr.length < n) {
        // remove one element from random position and add this element to the result array
        resultArr = resultArr.concat( // merge arrays
            srcArr.splice( // extract one random element
                Math.floor(Math.random() * srcArr.length),
                1
            )
        );
    }

    return resultArr;
}


SO'ya hoş geldiniz! Cevapları gönderirken, kodunuzun nasıl çalıştığını ve / veya OP'nin problemini nasıl çözdüğünü belirtmek önemlidir :)
Joel

0

2019

Bu Laurynas Mališauskas'ın cevabıyla aynıdır , sadece unsurlar benzersizdir (kopyaları yoktur).

var getMeRandomElements = function(sourceArray, neededElements) {
    var result = [];
    for (var i = 0; i < neededElements; i++) {
    var index = Math.floor(Math.random() * sourceArray.length);
        result.push(sourceArray[index]);
        sourceArray.splice(index, 1);
    }
    return result;
}

Şimdi "jQuery ile birden çok rastgele öğe nasıl elde edilir" sorusuna yanıt vermek için, işte burada:

var getMeRandomElements = function(sourceArray, neededElements) {
    var result = [];
    for (var i = 0; i < neededElements; i++) {
    var index = Math.floor(Math.random() * sourceArray.length);
        result.push(sourceArray[index]);
        sourceArray.splice(index, 1);
    }
    return result;
}

var $set = $('.someClass');// <<<<< change this please

var allIndexes = [];
for(var i = 0; i < $set.length; ++i) {
    allIndexes.push(i);
}

var totalRandom = 4;// <<<<< change this please
var randomIndexes = getMeRandomElements(allIndexes, totalRandom);

var $randomElements = null;
for(var i = 0; i < randomIndexes.length; ++i) {
    var randomIndex = randomIndexes[i];
    if($randomElements === null) {
        $randomElements = $set.eq(randomIndex);
    } else {
        $randomElements.add($set.eq(randomIndex));
    }
}

// $randomElements is ready
$randomElements.css('backgroundColor', 'red');

0

İşte bir diziyi değiştirerek veya değiştirmeden kolayca örneklemenizi sağlayan kullandığım bir işlev:

  // Returns a random sample (either with or without replacement) from an array
  const randomSample = (arr, k, withReplacement = false) => {
    let sample;
    if (withReplacement === true) {  // sample with replacement
      sample = Array.from({length: k}, () => arr[Math.floor(Math.random() *  arr.length)]);
    } else { // sample without replacement
      if (k > arr.length) {
        throw new RangeError('Sample size must be less than or equal to array length         when sampling without replacement.')
      }
      sample = arr.map(a => [a, Math.random()]).sort((a, b) => {
        return a[1] < b[1] ? -1 : 1;}).slice(0, k).map(a => a[0]); 
      };
    return sample;
  };

Bunu kullanmak basittir:

Değiştirme Olmadan (varsayılan davranış)

randomSample([1, 2, 3], 2) dönebilir [2, 1]

Değiştirme ile

randomSample([1, 2, 3, 4, 5, 6], 4) dönebilir [2, 3, 3, 2]


0
var getRandomElements = function(sourceArray, requiredLength) {
    var result = [];
    while(result.length<requiredLength){
        random = Math.floor(Math.random()*sourceArray.length);
        if(result.indexOf(sourceArray[random])==-1){
            result.push(sourceArray[random]);
        }
    }
    return result;
}

0

Hiç kimsenin bu yöntemden bahsetmediğine inanamıyorum, oldukça açık ve anlaşılır.

const getRnd = (a, n) => new Array(n).fill(null).map(() => a[Math.floor(Math.random() * a.length)]);

İki öğenin tekrarlanmayacağından emin değilsiniz.
Valery

-2

İşte en doğru cevap ve size Rastgele + Benzersiz öğeler verecek.

function randomize(array, n)
{
    var final = [];
    array = array.filter(function(elem, index, self) {
        return index == self.indexOf(elem);
    }).sort(function() { return 0.5 - Math.random() });

    var len = array.length,
    n = n > len ? len : n;

    for(var i = 0; i < n; i ++)
    {
        final[i] = array[i];
    }

    return final;
}

// randomize([1,2,3,4,5,3,2], 4);
// Result: [1, 2, 3, 5] // Something like this

Bunda rastgelelemeyle ilgili garip bir şey var - 9 denemeden 6'sında aynı sonuca ulaştım (8'lik bir n ve 148'lik bir dizi boyutuyla). Fisher-Yates yöntemine geçmeyi düşünebilirsiniz ; yaptığım şey bu ve şimdi çok daha iyi çalışıyor.
asetniop

Bu ikinci dereceden zaman alır çünkü kötü bir benzersizlik kontrolü yapar ve rastgele bir karşılaştırmayla sıralandığı için her öğeyi seçme şansı eşit değildir.
Ry-

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.