数组的随机洗牌
我需要随机洗牌以下数组:
int[] solutionArray = {1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1};
有什么函数可以做到这一点吗?
I need to randomly shuffle the following Array:
int[] solutionArray = {1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1};
Is there any function to do that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(30)
解决方案之一是使用排列来预先计算所有排列并存储在 ArrayList 中。Java
8 在 java.util.Random 类中引入了一个新方法 ints()。 ints() 方法返回无限的伪随机 int 值流。您可以通过提供最小值和最大值将随机数限制在指定范围内。
借助生成随机数,您可以迭代循环并将当前索引与随机数交换。
这就是如何生成空间复杂度为 O(1) 的随机数。
One of the solution is using the permutation to pre-compute all the permutations and stored in the ArrayList
Java 8 introduced a new method, ints(), in the java.util.Random class. The ints() method returns an unlimited stream of pseudorandom int values. You can limit the random numbers between a specified range by providing the minimum and the maximum values.
With the help of generating the random number, You can iterate through the loop and swap with the current index with the random number..
That's how you can generate a random number with O(1) space complexity.
没有随机解:
Without Random solution:
在Java中,我们可以使用Collections.shuffle方法对列表中的项目进行随机重新排序。
Groovy 3.0.0 添加了 shuffle 和 shuffled 方法 直接到列表或数组。
In Java we can use Collections.shuffle method to randomly reorder items in a list.
Groovy 3.0.0 adds the shuffle and shuffled methods to a List or array directly.
使用 Collections 来打乱原始类型数组有点过分了...
自己实现该函数非常简单,例如使用 费舍尔-耶茨洗牌:
Using Collections to shuffle an array of primitive types is a bit of an overkill...
It is simple enough to implement the function yourself, using for example the Fisher–Yates shuffle:
这是使用 ArrayList 的简单方法:
Here is a simple way using an
ArrayList
:这是一个有效且有效的 Fisher–Yates shuffle 数组函数:
或者
Here is a working and efficient Fisher–Yates shuffle array function:
or
集合 类有一个有效的改组方法,可以复制该方法,以免依赖于它:
Collections class has an efficient method for shuffling, that can be copied, so as not to depend on it:
具体查看
Collections
类随机播放(...)
。Look at the
Collections
class, specificallyshuffle(...)
.您在这里有几个选择。在洗牌方面,列表与数组有点不同。
如下所示,数组比列表快,原始数组比对象数组快。
示例持续时间
下面是随机播放的三种不同实现。如果您正在处理集合,则应该仅使用 Collections.shuffle。无需将数组包装到集合中只是为了对其进行排序。下面的方法实现起来非常简单。
ShuffleUtil 类
主要方法
洗牌通用列表
洗牌通用数组
洗牌原始数组
实用方法
将数组复制并转换为列表的简单实用方法,反之亦然。
Range 类
生成一个值范围,类似于 Python 的
range
函数。You have a couple options here. A list is a bit different than an array when it comes to shuffling.
As you can see below, an array is faster than a list, and a primitive array is faster than an object array.
Sample Durations
Below, are three different implementations of a shuffle. You should only use Collections.shuffle if you are dealing with a collection. There is no need to wrap your array into a collection just to sort it. The methods below are very simple to implement.
ShuffleUtil Class
Main Method
Shuffling a Generic List
Shuffling a Generic Array
Shuffling a Primitive Array
Utility Methods
Simple utility methods to copy and convert arrays to lists and vice-versa.
Range Class
Generates a range of values, similar to Python's
range
function.这是使用
Collections.shuffle
方法的完整解决方案:请注意,由于 Java 无法在
int[]
和Integer[] (以及
int[]
和List
)。Here is a complete solution using the
Collections.shuffle
approach:Note that it suffers due to Java's inability to smoothly translate between
int[]
andInteger[]
(and thusint[]
andList<Integer>
).使用 ArrayList可以帮助您解决洗牌问题,而无需应用大量逻辑并消耗更少的时间。这是我的建议:
Using
ArrayList<Integer>
can help you solving the problem of shuffling without applying much of logic and consuming less time. Here is what I suggest:下面的代码将实现对数组的随机排序。
来自: http: //www.programcreek.com/2012/02/java-method-to-shuffle-an-int-array-with-random-order/
The following code will achieve a random ordering on the array.
from: http://www.programcreek.com/2012/02/java-method-to-shuffle-an-int-array-with-random-order/
您现在可以使用 java 8:
You can use java 8 now:
这是使用 Apache Commons Math 3.x 的解决方案(仅适用于 int[] 数组):
http://commons.apache.org/proper/commons-math/javadocs/api-3.6.1 /org/apache/commons/math3/util/MathArrays.html#shuffle(int[])
另外,Apache Commons Lang 3.6 向 ArrayUtils 类引入了新的 shuffle 方法(用于对象和任何原始类型)。
http://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/ArrayUtils.html#shuffle-int:A-
Here is a solution using Apache Commons Math 3.x (for int[] arrays only):
http://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/util/MathArrays.html#shuffle(int[])
Alternatively, Apache Commons Lang 3.6 introduced new shuffle methods to the
ArrayUtils
class (for objects and any primitive type).http://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/ArrayUtils.html#shuffle-int:A-
顺便说一句,我注意到这段代码返回
ar.length - 1
个元素,因此如果您的数组有 5 个元素,则新的打乱数组将有 4 个元素。发生这种情况是因为 for 循环显示i>0
。如果更改为i>=0
,所有元素都会被打乱。By the way, I've noticed that this code returns a
ar.length - 1
number of elements, so if your array has 5 elements, the new shuffled array will have 4 elements. This happens because the for loop saysi>0
. If you change toi>=0
, you get all elements shuffled.这是数组的泛型版本:
考虑到 ArrayList 基本上只是一个数组,因此建议使用 ArrayList 而不是显式数组并使用 Collections.shuffle()。然而,性能测试并没有显示出上述和 Collections.sort() 之间有任何显着差异:
Apache Commons 实现 MathArrays.shuffle 仅限于 int[],并且性能损失可能是由于使用的随机数生成器造成的。
Here is a Generics version for arrays:
Considering that ArrayList is basically just an array, it may be advisable to work with an ArrayList instead of the explicit array and use Collections.shuffle(). Performance tests however, do not show any significant difference between the above and Collections.sort():
The Apache Commons implementation MathArrays.shuffle is limited to int[] and the performance penalty is likely due to the random number generator being used.
我在一些答案中看到了一些遗漏的信息,所以我决定添加一个新的。
Java 集合 Arrays.asList 采用 T
(T ...)
类型的 var-arg。如果传递一个原始数组(int 数组),asList 方法将推断并生成一个List
,它是一个单元素列表(其中一个元素是原始数组)。如果你打乱这个元素列表,它不会改变任何事情。因此,首先必须将原始数组转换为包装对象数组。为此,您可以使用 apache.commons.lang 中的 ArrayUtils.toObject 方法。然后将生成的数组传递给 List 并最后对其进行洗牌。
I saw some miss information in some answers so i decided to add a new one.
Java collections Arrays.asList takes var-arg of type T
(T ...)
. If you pass a primitive array (int array), asList method will infer and generate aList<int[]>
, which is a one element list (the one element is the primitive array). if you shuffle this one element list, it won`t change any thing.So, first you have to convert you primitive array to Wrapper object array. for this you can use
ArrayUtils.toObject
method from apache.commons.lang. then pass the generated array to a List and finaly shuffle that.这是另一种打乱列表的方法
从原始列表中选择一个随机数并将其保存到另一个列表中。然后从原始列表中删除该数字。原始列表的大小将不断减少,直到所有元素都移动到新列表中列表。
Here's another way to shuffle a list
Pick a random number from the original list and save it in another list.Then remove the number from the original list.The size of the original list will keep decreasing by one until all elements are moved to the new list.
Groovy 的一个简单解决方案:
这将对数组列表的所有元素进行随机排序,从而归档所有元素打乱所需的结果。
A simple solution for Groovy:
This will sort all elements of the array list randomly which archives the desired result of shuffling all elements.
使用 Guava 的
Ints.asList()
它很简单:Using Guava's
Ints.asList()
it is as simple as:使用随机类
Using the Random Class
我正在考虑这个非常受欢迎的问题,因为没有人编写过随机复制版本。样式大量借用自
Arrays.java
,因为现在谁没有掠夺 Java 技术呢?包括通用和 int 实现。I'm weighing in on this very popular question because nobody has written a shuffle-copy version. Style is borrowed heavily from
Arrays.java
, because who isn't pillaging Java technology these days? Generic andint
implementations included.这就是克努斯洗牌算法。
This is knuth shuffle algorithm.
还有另一种方法,不发布
这种方式更容易,取决于上下文
There is another way also, not post yet
that way more easy, depended of the context
数组中随机洗牌的最简单解决方案。
The most simple solution for this Random Shuffling in an Array.
最简单的洗牌代码:
Simplest code to shuffle:
int[]
到List
Collections.shuffle
方法随机播放int[]
toList<Integer>
Collections.shuffle
method您应该使用
Collections.shuffle()
。但是,您无法直接操作原始类型的数组,因此您需要创建一个包装类。试试这个。
并
输出:
You should use
Collections.shuffle()
. However, you can't directly manipulate an array of primitive types, so you need to create a wrapper class.Try this.
And
output: