Front-end interview questions: efficiently randomly select elements in an array

Source: Internet
Author: User
Tags shuffle

There's a front-end topic about this: how to quickly get a partial element from a huge array, given the performance problem.

For example, there are 100K elements in the array, which randomly selects 10K elements.

In order to demonstrate the convenience of simplifying the data, we first give the solution and then use the larger data to test the performance comparison.

Conventional Solutions

The conventional approach is not difficult, generating a 0 to the array length minus 1 of the random number, which is the selected element in the original array subscript, after obtaining the element to save the value to another array at the same time through the array of splice method to remove the element from the original array, to ensure that the next time not to be repeated.

According to the above idea, the code is probably like this:

The total number of elements, in order to facilitate the demonstration here to take a smaller number such as 5, representing a total of 5 elements var total_num = 5,    //To get the number, indicating that we want to randomly take 3 elements from the original array    COUNT = 3,    // Initializes the original array with a random string    arr = new Array (Total_num + 1). Join (' 0 '). Split ('). Map (function () {        return math.random (). ToString (substr (2);    }),    //array of saved results    = [];console.log (' Original array: ', arr);//Start our selection process for (var i = COUNT- 1; I >= 0; i--) {    //randomly take an element out of the original array    var index = Math.floor (Math.random () * arr.length);    Press-in result array    Result.push (Arr[index]);    Removes the element from the original array    arr.splice (index, 1);}; Console.log (' Result array: ', result);

Running results such as:

Of course, for illustrative purposes, the 100 000 large number of topics required is simplified to a total of 5, and only 3 are taken.

It is entirely feasible to look at the test results.

But there is a problem: in order to not repeat the selected elements for the next random time, we remove the selected elements from the original array through the Splice method, but the process of the splice method itself is the process by which the array re-maintains its element index. This means that all elements after the selected element need to be moved forward one position to regenerate a compact array, and it can be imagined that if we take the 1th element in the original array, then the 99 999 elements will need to be changed to complete the operation of the reorganization array, which is a bit time consuming.

Using Shuffle algorithm

Another way of thinking can be this, since you want to randomly select, I can first put the elements of the array first, and then how much to take from the beginning of the line. A mention of random, naturally think of shuffle algorithm, and about the shuffle algorithm has a very classic and efficient fisher-yates algorithm, this algorithm I have written before a blog introduced.

This idea is a bit retrograde than the previous method, the focus is random, so each time it produces a random subscript to the original array to take, now is the array elements randomly scrambled, then to normal fetch. Since the shuffling algorithm is very efficient and eliminates the need to reorganize the array, performance should be improved compared to the former.

The last code to be implemented in this way is probably the same:

The total number of elements, in order to facilitate the demonstration here to take a smaller number such as 5, representing a total of 5 elements var total_num = 5,    //To get the number, indicating that we want to randomly take 3 elements from the original array    COUNT = 3,    // Initializes the original array with a random string    arr = new Array (Total_num + 1). Join (' 0 '). Split ('). Map (function () {        return math.random (). ToString (substr (2);    }),    //array of saved results    = [];console.log (' Original array: ', arr);//randomization of the original array arr = Shuffle (arr); /select element result = Arr.slice (0, COUNT), console.log (' Result array: ', result), function shuffle (array) {    var m = array.length,        T, I;    If there are elements    left ... while (m) {        //random selection of an element        ... i = Math.floor (Math.random () * m--);        Swap with current element        t = array[m];        ARRAY[M] = Array[i];        Array[i] = t;    }    return array;}

The above code contains the classic shuffle algorithm fisher-yates shuffle algorithm, namely the shuffle function. Please refer to my other blog for details.

Operation Result:

From the results, this method is also feasible.

Fine think or there is a problem, for a larger array, no matter how efficient your shuffle algorithm (even if the above fisher-yates algorithm time complexity is O (n)), to random the entire array is still very large engineering it.

So the quest for this subject is not over yet. When I asked questions on StackOverflow, I didn't get a surprising answer, but one of the answers reminded me that I could improve the method above.

Take only what you need

That is, we do not have to randomly drop the entire array, after we take the required number of elements, can be fisher-yates Chaos method Abort!

The idea is very obvious, so you can save a lot of meaningless operations.

So the final implementation is probably like this:

The total number of elements, in order to facilitate the demonstration here to take a smaller number such as 5, representing a total of 5 elements var total_num = 5,    //To get the number, indicating that we want to randomly take 3 elements from the original array    COUNT = 3,    // Initializes the original array with a random string    arr = new Array (Total_num + 1). Join (' 0 '). Split ('). Map (function () {        return math.random (). ToString (substr (2);    }),    //array of saved results    = [];console.log (' Original array: ', arr);//This code is made by fisher-yates The Shuflle algorithm changes to var m = arr.length,    t, I;while (M && result.length < COUNT) {    //random selection of an element    ... i = Math.floor (Math.random () * m--);    t = arr[m];    ARR[M] = Arr[i];    Arr[i] = t;    Result.push (Arr[m]);} Console.log (' Result array: ', result);

The above code modifies the fisher-yates algorithm slightly, and then stops after obtaining the element that satisfies the requirement, so it is more scientific than the previous approach.

Operation Result:

Performance comparison

Finally, the time-consuming comparison of the above three methods is given, which returns the number of array elements that need to be manipulated to the 100 000来 required in the topic.

Is the result of running the test on the Jsperf, and the details can be rerun with the Point test page. The larger the number, the better. The top-down sequence is the three methods described in this article.

Summarize

At present, the PO Master can only think of these, better practices still need further exploration.

Refernce

The chaotic algorithm fisher–yates Shuffle http://www.cnblogs.com/Wayou/p/fisher_yates_shuffle.html by the shuffle

Front-end interview questions: efficiently randomly select elements in an array

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.