Generate random number without duplicate in certain range

99封情书 提交于 2019-12-06 11:03:47

Create a list if all numbers in the range, then shuffle the list:

List<Integer> numbers = new ArrayList<>();
// eg for range 3-5
for (int i = 3; i <= 5; i++)
    numbers.add(i);
Collections.shuffle(numbers);

Now use them in their new (random) order.

Unless your range is very large (millions) this will work fine.


Java8 version:

List<Integer> numbers = IntStream.rangeClosed(3, 5).boxed().collect(Collectors.toList());
Collections.shuffle(numbers);

Well, you could store your numbers an an ArrayList<>. Every time you generate a random number, see if the ArrayList<> contains the number. If it does, generate another number and repeat the process.

Better yet, use a Set <>.

I know it's late, but could be helpful for future reference. You can create your own custom Random class:

//Generates random integers without repetition between two given numbers both inclusive
public class Random {
    private int start;
    private int end;
    private Stack<Integer> numbers = new Stack<>();
    public Random(int start, int end){
        this.start = start;
        this.end = end;
    }
    private void loadNumbers(){
         for (int i=start;i<=end;i++){
                numbers.push(i);
            }
         Collections.shuffle(numbers);
    }
    public int nextInt(){
        if (numbers.empty()) loadNumbers();
        return numbers.pop();
    }
}

And use it like:

Random rand = new Random(1,20);
for(int i=0; i<100;i++){
    System.out.print(rand.nextInt()+ " ");
}

To get numbers ranging from 1-3, 2-4, 3-5, etc, change this

num[i] = (int)(Math.random()*3);

to this

num[i] = rand.nextInt(2) + 1 + i;

You'll need to import Random and add Random rand = new Random(); before using it.

The formula to generate random number in the range is :

    Random rn = new Random();
    int range = maximum - minimum + 1;
    int randomNum =  rn.nextInt(range) + minimum;

so in one line you can generate as like this

    int num1 = new Random().nextInt(3-1+1) + 1;
    int num2 = new Random().nextInt(4-2+1) + 1;
    int num3 = new Random().nextInt(5-2+1) + 1;

or

    num[i] = new Random.nextInt(range[i]) + 1 + i;

and then you can do your logic stuff to set the resource. Happy Coding :)

The best possible and most efficient way to generate and store unique numbers would be to create a HashSet that holds your data. Generate the number and then try to add it to the HashSet. If the add method returns false, then it means that the number already exists in the set and hence re-generate a number. The advantage of using this method over the ArrayList is that this has a time complexity of O(1) while using the contains() method (from ArrayList) would result in a time complexity of O(n) - efficiency decreases as size increases.

int base = (int)Math.random(); System.out.print(base);

int change = ((int)Math.random()) % 3;

if(change == 0) { change++; System.out.print(base + 1); System.out.println(base + 2); }

else { System.out.print(base + 2); System.out.println(base + 1); }

You can also use Random number generation to fill a HashSet for a fixed range.

Reduce the total amount every run, and appropriately increment the result.

static int[] randomRange(Random random, int cap, int count) {
    assert count < cap && count > 0 && cap > 0;
    int[] output = new int[count];
    // initial placeholder. use 0x7FFFFFFF for convenience is also OK.
    Arrays.fill(output, -1);
    for(int i = 0; i < count; i++) {
        // you only have (cap - i) options left
        int r = random.nextInt(cap - i);
        // iterate through a sorted array
        for(int got : output) {
            // ignore placeholders
            if(got != -1 && got <= r) {
                // the generated random int counts number of not-yet-picked ints
                r++;
            }
        }
        // add to array in a sorted manner
        addToArray(output, r);
    }
    return output;
}

static void addToArray(int[] array, int value) {
    for(int i = 1; i <= array.length; i++) {
        if(i == array.length || array[i] >= value) {
            // shift smaller values one place left
            // this includes -1. If you use 0x7FFFFFFF,
            // you may have to sort the array the other way round.
            System.arraycopy(array, 1, array, 0, i - 1);
            array[i - 1] = value;
            return;
        }
    }
}

This algorithm has a disadvantage that its output is sorted. It is, of course, also possible to keep track of two arrays, one sorted (for increment) and one unsorted (for return).

The above code snippet was tested through cap = 20, count = 10 and cap = 20, count = 20 twice each.

Suresh
Integer[] a = new Integer[3];
Random r = new Random();
for (int i = 0; i < a.length; i++) { 
        a[i] = r.nextInt(3-1) + 1;  
}
Collections.shuffle(Arrays.asList(a), r);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!