java 随机数 数组_用Java随机播放数组的最佳解决方案

java 随机数 数组

I recently met a small issue on creating a new randomly ordered array based on an old one. To speak shortly, the final goal is to get a shuffled array.

我最近遇到了一个小问题,该问题是基于旧数组创建一个新的随机排序数组。 简而言之,最终目标是获得一个经过改组的数组。

Visit https://pitayan.com/posts/javascript-shuffle-array/ to read original article with source code highlights.

请访问 https://pitayan.com/posts/javascript-shuffle-array/阅读带有源代码重点的原始文章。

The following is my solution after a few moment’s experiment before I search the web. (I thought I could do it myself :p)

以下是在搜索网络之前经过一番实验后的解决方案。 (我以为自己可以做到:p)

var arr = [1, 2, 3, 4, 5, 6, 7]function shuffle (arr) {
let i = 0,
res = [],
index while (i <= arr.length - 1) {
index = Math.floor(Math.random() * arr.length) if (!res.includes(arr[index])) {
res.push(arr[index])
i++
}
} return res
}// expected
arr = shuffle(arr)
// [6, 3, 4, 1, 7, 2, 5]

As you can see that this is not a good way handle shuffling, so I decide to do some researches over it.

如您所见,这不是处理混洗的好方法,因此我决定对此进行一些研究。

After looking for some answers on google and stackoverflow, I found a most satisfying solution to shuffle an array. (The answer has been there since 2010… But, very qualified indeed.)

在google和stackoverflow上寻找了一些答案之后,我找到了一个最令人满意的解决方案,可以对数组进行随机排序。 (答案自2010年以来一直存在。但是,确实很合格。)

First things first, let’s take a look at the answer. It’s quite simple but fast enough.

首先,让我们看一下答案。 这很简单,但是足够快。

function shuffle(array) {
var currentIndex = array.length, temporaryValue, randomIndex; // While there remain elements to shuffle...
while (0 !== currentIndex) { // Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1; // And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
} return array;
}

为什么我的解决方案不好 (Why My Solution is Bad)

At the beginning, I was just thinking about creating new random indexes within a while loop and push the old array element to a new array as return.

刚开始,我只是想在while循环中创建新的随机索引,并将旧的数组元素作为返回值推到新数组中。

while (i <= arr.length - 1) {
// create random index
index = Math.floor(Math.random() * arr.length) // insert the element to new array
if (!res.includes(arr[index])) {
res.push(arr[index])
i++
}
}

It works well with very satisfying returnings. But the time complexity was pretty bad. In the while loop, it checks if the element to be inserted exists in the new array for each of the loop round. This results in O(n2).

它的收益令人满意,效果很好。 但是时间复杂度很差。 在while循环中,它针对每个循环回合检查要插入的元素是否在新数组中。 结果为O(n2)

If an array isn’t that big, then my function was just fine. But the truth is, my project needs to generate a list with more than 1000 elements. So it’s better to optimize the algorithm. (I think it’s always better to do such optimization. Don’t be afraid to mean to computers :D)

如果数组不是那么大,那么我的功能就很好。 但是事实是,我的项目需要生成一个包含1000多个元素的列表。 因此最好对算法进行优化。 (我认为进行这样的优化总是更好。不要害怕对计算机表示:D)

Fisher-Yates随机播放 (The Fisher–Yates Shuffle)

The stackoverflow’s answer seems quite simple, however in fact it uses an algorithm invented by Ronald Fisher and Frank Yates.

stackoverflow的答案似乎很简单,但是实际上它使用了Ronald FisherFrank Yates发明的算法。

The Fisher–Yates shuffle is an algorithm for generating a random permutation of a finite sequence — in plain terms, the algorithm shuffles the sequence.

Fisher-Yates混洗是一种用于生成有限序列的随机置换的算法-简而言之,该算法可对序列进行混洗。

…and is also known as the Knuth shuffle after Donald Knuth.

…也称为 Donald Knuth 之后的Knuth洗牌

— From Wikipedia

—来自 维基百科

There’s an old blog article that visualizes the shuffle algorithm. https://bost.ocks.org/mike/shuffle/

有一篇旧的博客文章可视化混洗算法。 https://bost.ocks.org/mike/shuffle/

The shuffle function is a description of the algorithm.

shuffle功能是对算法的描述。

function shuffle(array) {
var currentIndex = array.length, temporaryValue, randomIndex; // While there remain elements to shuffle...
while (0 !== currentIndex) { // Create a random index to pick from the original array
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1; // Cache the value, and swap it with the current element
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
} return array;
}

The solution is very good, but it still has some improving potentials. I believe making a pure function here makes more sense. So I’d rather return a new array than modifying the original argument as a side effect.

解决方案非常好,但仍有改进的潜力。 我相信在这里做一个纯函数更有意义。 因此,我宁愿返回一个新数组,也不愿修改原始参数作为副作用。

To avoid modifying the original data, I can also create a clone while passing the arugment.

为了避免修改原始数据,我还可以在传递标签时创建一个克隆。

shuffle(arr.slice(0))

其他变化 (Other Variations)

There are some honorable alternatives to the solution I found on stackoverflowwhich I think is properly optimized.

对于我在stackoverflow上发现的解决方案,有一些光荣的替代方案,我认为它们已经适当优化。

达斯滕费尔德洗牌 (The Durstenfeld Shuffle)

This solution appears on the stackoverflow page. I found a gist memo in the end.

此解决方案出现在stackoverflow页面上。 最后我找到了要点备忘录。

https://gist.github.com/webbower/8d19b714ded3ec53d1d7ed32b79fdbac

https://gist.github.com/webbower/8d19b714ded3ec53d1d7ed32b79fdbac

// Pre-ES6
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}// ES6+
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}

数组扩展方法 (Array extension method)

Actually, I’d prefer this one due to its simplicity and a small trick of round numbers. The trick here is to use >>> (unsigned right shift operator) instead of Math.floor.

实际上,由于它的简单性和一小部分的整数运算,我更希望使用它。 这里的技巧是使用>>> ( 无符号右移运算符 )代替Math.floor

Array.prototype.shuffle = function() {
let m = this.length, i;
while (m) {
i = (Math.random() * m--) >>> 0;
[this[m], this[i]] = [this[i], this[m]]
}
return this;
}

Okay, that’s all for the research. Hope you also get a good understanding of the shuffle algorithm from this article. If you think this article is great, please share it on social networks.

好的,这就是研究的全部内容。 希望您也对本文的shuffle算法有所了解。 如果您认为这篇文章很棒,请在社交网络上分享。

Thank you reading!

谢谢阅读!

翻译自: https://medium.com/dev-genius/jthe-optimal-solution-to-shuffle-an-array-in-javascript-2d9c8ac066d9

java 随机数 数组

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值