java 如何拥有唯一的随机数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3395911/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 01:38:36  来源:igfitidea点击:

How to have unique random number?

javarandom

提问by Shishir.bobby

This is how i am generating a unique no in between 1 to 6 and getting appropriate images from the drawable folder.

这就是我如何在 1 到 6 之间生成一个唯一的 no 并从 drawable 文件夹中获取适当的图像。

Random rand = new Random();
// n = the number of images, that start at idx 1
rndInt = rand.nextInt(6) + 1; 
String imgName = "card" + rndInt;
int id = getResources().getIdentifier(imgName, "drawable", getPackageName());
imgView.setImageResource(id);

What i want is, I have to call this method 7 times, and each time this method should return a unique random no. so that none of the already chosen numbers will come up again.

我想要的是,我必须调用这个方法 7 次,每次这个方法都应该返回一个唯一的随机数。这样已经选择的数字都不会再次出现。

回答by Dan Dyer

The usual approach to this kind of problem is to create a list containing each of the possible values and shuffle it (use Collections.shuffle). You then consume one item from the list each time you need a value. This will ensure that you don't use the same value more than once but still allows for a random order.

解决此类问题的常用方法是创建一个包含每个可能值的列表并将其打乱(使用Collections.shuffle)。然后,每次需要一个值时,从列表中使用一项。这将确保您不会多次使用相同的值,但仍允许使用随机顺序。

回答by Zeriab

Here is an example class which creates a random permutation using the approach Dan Dyer suggested. It ensures that each .next() calls gives a new number up to the number given in the constructor. After that it wraps around and gives the same sequence again. This can be useful for shuffling a playlist.

这是一个示例类,它使用 Dan Dyer 建议的方法创建随机排列。它确保每个 .next() 调用都会给出一个新数字,直到构造函数中给出的数字为止。之后它环绕并再次给出相同的序列。这对于调整播放列表很有用。

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class RandomPermutation{
    private List<Integer> list;
    private int index;

    /**
     * Create a random permutation the sequence of numbers 0, 1, ... , n - 1.
     * @param n Range specifier, must be positive
     */
    public RandomPermutation(int n) {
        if (n <= 1) {
            throw new IllegalArgumentException(
                    "Positive number expected, got: " + n);
        }
        list = new ArrayList<Integer>();
        newList(n);
    }

    /**
     * Creates a new list
     */
    public void newList(int n) {
        index = -1;
        list.clear();
        for (int i = 0; i < n; i++) {
            list.add(i);
        }
        Collections.shuffle(list);
    }

    /**
     * Retrieve the next integer in sequence. 
     */
    public int next() {
        index = (index + 1) % list.size();
        return list.get(index);
    }
}

Btw. do not use the approach Snake used. It is not only because it will freeze once all numbers have been used. That can be fixed. The problem is more that the procedure runs slower and slower as more and more numbers are in the listIdontWantAnymore. With just 6 numbers it's not a problem, but it can cause quite a significant slowdown if the range is large. Consider choosing between 10000 numbers. After 9900 numbers have been chosen there is a 1% chance of hitting a good number. after 9990 numbers there is a 0.1% chance of hitting a good number and etc.

顺便提一句。不要使用 Snake 使用的方法。这不仅是因为一旦使用了所有数字,它就会冻结。那可以解决。问题在于,随着listIdontWantAnymore 中的数字越来越多,程序运行得越来越慢。只有 6 个数字这不是问题,但如果范围很大,它可能会导致相当大的减速。考虑在 10000 个数字之间进行选择。选择 9900 个号码后,有 1% 的机会中奖号码。在 9990 个号码之后,有 0.1% 的机会击中一个好号码等等。

Here is an example of how you can use the class:

以下是如何使用该类的示例:

static RandomPermutation randomPerm = new RandomPermutation(7)

int NextRandomNumber() {
    return randomPerm.next() + 1;
}

回答by arslan haktic

Here's the easiest code to do it and store into an array without any repetition:

这是最简单的代码,可以不重复地存储到数组中:

Random rand = new Random();
int[] ar;
ar = new int[5];

int random = 0;
int [] result_arr=new int[5];
boolean flag=false;

for(int i=0;i<5;i++)
{  
    ar[i]=0;

    do{
        random =rand.nextInt(10);
        flag=false;
        for(int j=0;j<i;j++)
        {
            if(ar[j]==random)
            flag=true;
        }
        if(!flag)
        {
            ar[i]=random;
            break;
        }
     }
     while(true) ;
}

this will create unique numbers in the array

这将在数​​组中创建唯一的数字

回答by Stephen C

For your particular use-case, this should do the trick.

对于您的特定用例,这应该可以解决问题。

Random rand = new Random();
// n = the number of images
List<String> imgNames = new ArrayList<String>(n);
for (int i = 0; i < n; i++) { 
    imgNames.add("card" + (i + 1)) 
}
while (!imageNames.isEmpty()) {
    String imgName = imgNames.remove(rand.next(imageNames.size());
    int id = getResources().getIdentifier(imgName, "drawable", getPackageName());
    imgView.setImageResource(id);
}

Beware that this does not scale well as ngets large. The remove operation is O(n)for an ArrayListor a LinkedList. But for nin the hundreds or thousands, this is probably insignificant compared with loading and displaying the images.

请注意,随着n变大,这不会很好地扩展。删除操作是O(n)针对 aArrayList或 a 的LinkedList。但是对于n成百上千的图像,与加载和显示图像相比,这可能微不足道。

Also, as the comments noted "unique random numbers" is a contradiction in terms. What you are after is a random permutationof the set of numbers from 1to n. My solution gives you this without an explicit "shuffling" step, and that's sufficient for your use-case.

此外,正如评论指出的那样,“唯一随机数”在术语上是矛盾的。您所追求的是从到的一组数字的随机排列。我的解决方案在没有明确的“改组”步骤的情况下为您提供了这一点,这对于您的用例来说已经足够了。1n

回答by Arafangion

Generate a list of numbers containing every number you will use. (Which is fine, given that we are talking about a small range, where "N" is "somewhere less than a thousand")

生成包含您将使用的每个数字的数字列表。(这很好,因为我们谈论的是一个小范围,其中“N”是“小于一千的地方”)

When you choose a number, select a random index between 0 and sizeof(list), that number becomes the index of that list.

当您选择一个数字时,在 0 和 sizeof(list) 之间选择一个随机索引,该数字成为该列表的索引。

Delete that list index and return the number.

删除该列表索引并返回数字。

(It is an exercise to the reader to determine what kind of "list" is appropriate here.)

(这是读者的一个练习,以确定此处适合哪种“列表”。)

回答by tc.

Use a linear congruential generatorwith appropriately chosen parameters.

Use a linear congruential generatorwith appropriately chosen parameters.

回答by Snake

Create a static list of possibilities you've already gotten.

创建您已经获得的可能性的静态列表。

static ArrayList<int> listIdontWantAnymore = new ArrayList<int>();

int NextRandomNumber() {
    Random random = new Random();
    int myRandomInt;

    do {
        myRandomInt = random.NextInt(6) + 1;
    } while(listIdontWantAnymore.Contains(myRandomInt));

    listIdontWantAnymore.Add(myRandomInt);

    // now your 'myRandomInt' is what you want it to be.
    return myRandomInt;
}