简体   繁体   English

唯一随机生成的整数的Java数组

[英]Java Array of unique randomly generated integers

public static int[] uniqueRandomElements (int size) {

    int[] a = new int[size];

    for (int i = 0; i < size; i++) {
        a[i] = (int)(Math.random()*10);

        for (int j = 0; j < i; j++) {
            if (a[i] == a[j]) {
                a[j] = (int)(Math.random()*10);
            }
        }   
    }

    for (int i = 0; i < a.length; i++) {
        System.out.print(a[i]+" ");
    }
    System.out.println();
    return a;
}

I have a method above which should generate an array of random elements that the user specifies.我上面有一个方法,它应该生成用户指定的随机元素数组。 The randomly generated integers should be between 0 and 10 inclusive.随机生成的整数应介于 0 和 10 之间。 I am able to generate random integers but the problem I have is checking for uniqueness.我能够生成随机整数,但我遇到的问题是检查唯一性。 My attempt to check for uniqueness is in my code above but the array still contains duplicates of integers.我在上面的代码中尝试检查唯一性,但数组仍然包含整数的重复项。 What am I doing wrong and could someone give me a hint?我做错了什么,有人可以给我一个提示吗?

for (int i = 0; i < size; i++) {
    a[i] = (int)(Math.random()*10);

    for (int j = 0; j < i; j++) {
        if (a[i] == a[j]) {
            a[j] = (int)(Math.random()*10); //What's this! Another random number!
        }
    }   
}

You do find the duplicate values.您确实找到了重复值。 However, you replace it with another random number that may be a duplicate.但是,您将其替换为另一个可能重复的随机数。 Instead, try this:相反,试试这个:

for (int i = 0; i < size; i++) {
    a[i] = (int)(Math.random()*10);//note, this generates numbers from [0,9]

    for (int j = 0; j < i; j++) {
        if (a[i] == a[j]) {
            i--; //if a[i] is a duplicate of a[j], then run the outer loop on i again
            break;
        }
    }  
}

However, this method is inefficient.然而,这种方法效率低下。 I recommend making a list of numbers, then randomizing it:我建议制作一个数字列表,然后将其随机化:

ArrayList<Integer> a = new ArrayList<>(11);
for (int i = 0; i <= 10; i++){ //to generate from 0-10 inclusive. 
                               //For 0-9 inclusive, remove the = on the <=
    a.add(i);
}
Collections.shuffle(a);
a = a.sublist(0,4);
//turn into array

Or you could do this:或者你可以这样做:

ArrayList<Integer> list = new ArrayList<>(11);
for (int i = 0; i <= 10; i++){
    list.add(i);
}
int[] a = new int[size];
for (int count = 0; count < size; count++){
    a[count] = list.remove((int)(Math.random() * list.size()));
}

If you have a duplicate you only regenerate the corresponding number once.如果您有重复,则只能重新生成相应的数字一次。 But it might create another duplicate.但它可能会创建另一个副本。 You duplicate checking code should be enclosed in a loop:你重复的检查代码应该包含在一个循环中:

while (true) {
    boolean need_to_break = true;
    for (int j = 0; j < i; j++) {
        if (a[i] == a[j]) {
            need_to_break = false; // we might get another conflict
            a[j] = (int)(Math.random()*10);
        }
    }
    if (need_to_break) break;
}   

But make sure that size is less than 10 , otherwise you will get an infinite loop.但请确保size小于10 ,否则您将获得无限循环。

Edit : while the above method solves the problem, it is not efficient and should not be used for large sized arrays.编辑:虽然上述方法解决了问题,但效率不高,不应用于大型数组。 Also, this doesn't have a guaranteed upper bound on the number of iterations needed to finish.此外,这对完成所需的迭代次数没有保证的上限。

A better solution (which unfortunately only solves second point) might be to generate a sequence of the distinct numbers you want to generate (the 10 numbers), randomly permute this sequence and then select only the first size elements of that sequence and copy them to your array.一个更好的解决方案(不幸的是只解决了第二点)可能是生成一个你想要生成的不同数字的序列( 10数字),随机排列这个序列,然后只选择该序列的第一个size元素并将它们复制到你的阵列。 You'll trade some space for a guarantee on the time bounds.你会用一些空间换取时间范围内的保证。

int max_number = 10;
int[] all_numbers = new int[max_number];
for (int i = 0; i < max_number; i++)
    all_numbers[i] = i;

/* randomly permute the sequence */
for (int i = max_number - 1; i >= 0; i--) {
    int j = (int)(Math.random() * i); /* pick a random number up to i */

    /* interchange the last element with the picked-up index */
    int tmp = all_numbers[j];
    all_numbers[j] = a[i];
    all_numbers[i] = tmp;
}

/* get the a array */
for (int i = 0; i < size; i++)
    a[i] = all_numbers[i];

Or, you can create an ArrayList with the same numbers and instead of the middle loop you can call Collections.shuffle() on it.或者,您可以创建一个具有相同数字的ArrayList ,而不是中间循环,您可以在其上调用Collections.shuffle() Then you'd still need the third loop to get elements into a .然后,你仍旧需要第三环获得元素融入a

It might work out faster to start with a sequential array and shuffle it.顺序数组开始并对其进行洗牌可能会更快。 Then they will all be unique by definition .那么它们在定义上都是独一无二的

Take a look at Random shuffling of an array , and at the Collections.shuffle function.看一看Random shuffle of an array和 Collections.shuffle 函数。

int [] arr = [1,2,3,.....(size)]; //this is pseudo code

Collections.shuffle(arr);// you probably need to convert it to list first

If you just don't want to pay for the added overhead to ArrayList, you can just use an array and use Knuth shuffle :如果您只是不想为 ArrayList 的额外开销付费,您可以只使用一个数组并使用Knuth shuffle

public Integer[] generateUnsortedIntegerArray(int numElements){
    // Generate an array of integers
    Integer[] randomInts = new Integer[numElements];
    for(int i = 0; i < numElements; ++i){
        randomInts[i] = i;
    }
    // Do the Knuth shuffle
    for(int i = 0; i < numElements; ++i){
        int randomIndex = (int)Math.floor(Math.random() * (i + 1));
        Integer temp = randomInts[i];
        randomInts[i] = randomInts[randomIndex];
        randomInts[randomIndex] = temp;
    }
    return randomInts;
}

The above code produces numElements consecutive integers, without duplication in a uniformly random shuffled order.上面的代码生成 numElements 个连续整数,没有以均匀随机打乱顺序重复。

 import java.util.Scanner;
 class Unique
{
public static void main(String[]args)
{
    int i,j;
    Scanner in=new Scanner(System.in);
    int[] a=new int[10];
    System.out.println("Here's a unique no.!!!!!!");
    for(i=0;i<10;i++)
    {
        a[i]=(int)(Math.random()*10);
        for(j=0;j<i;j++)
        {
            if(a[i]==a[j])
            {
                i--;

            }
        }   
    }
    for(i=0;i<10;i++)
    {
        System.out.print(a[i]);
    }
}
}

Input your size and get list of random unique numbers using Collections.使用 Collections 输入您的尺寸并获取随机唯一数字列表。

public static ArrayList<Integer> noRepeatShuffleList(int size) {
    ArrayList<Integer> arr = new ArrayList<>();
    for (int i = 0; i < size; i++) {
        arr.add(i);
    }
    Collections.shuffle(arr);
    return arr;
}

Elaborating Karthik's answer.详细说明 Karthik 的回答。

int[] a = new int[20];

for (int i = 0; i < size; i++) {
    a[i] = (int) (Math.random() * 20);

    for (int j = 0; j < i; j++) {
        if (a[i] == a[j]) {
            a[i] = (int) (Math.random() * 20); //What's this! Another random number!
            i--;
            break;
        }
    }
}
    int[] a = new int [size];

    for (int i = 0; i < size; i++) 
    {
        a[i] = (int)(Math.random()*16); //numbers from 0-15
        for (int j = 0; j < i; j++) 
        {
            //Instead of the if, while verifies that all the elements are different with the help of j=0
            while (a[i] == a[j])
            {
                a[i] = (int)(Math.random()*16); //numbers from 0-15
                j=0;
            }
        }
    }

    for (int i = 0; i < a.length; i++)
    {
        System.out.println(i + ".   " + a[i]);
    }
//Initialize array with 9 elements
int [] myArr = new int [9];
//Creating new ArrayList of size 9
//and fill it with number from 1 to 9
ArrayList<Integer> myArrayList = new ArrayList<>(9);
    for (int i = 0; i < 9; i++) {
        myArrayList.add(i + 1);
        }
//Using Collections, I shuffle my arrayList
Collections.shuffle(myArrayList);
//With for loop and method get() of ArrayList
//I fill my array
for(int i = 0; i < myArrayList.size(); i++){
    myArr[i] = myArrayList.get(i);
    }

//printing out my array
for(int i = 0; i < myArr.length; i++){
    System.out.print(myArr[i] + " ");
        }

You can try this solution:你可以试试这个解决方案:

public static int[] uniqueRandomElements(int size) {
    List<Integer> numbers = IntStream.rangeClosed(0, size).boxed().collect(Collectors.toList());
    return Collections.shuffle(numbers);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM