Генерация случайных чисел между 2 диапазонами для вставки связанного списка - PullRequest
0 голосов
/ 02 августа 2020

Привет, я пытаюсь сгенерировать случайное число между двумя наборами диапазонов (-30, -10) и (10,30) для хранения в узле LinkedList. Если сгенерированное число отрицательное, мы вставляем этот элемент и следующий (независимо от его значения) в «начало» списка. Если сгенерированное число положительное, то этот и следующий элементы будут сохранены в «хвосте». Это то, что у меня есть.

public class CAO_QUANG_JUIN_P4 {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    //////////////////////////bloc1:Decleration des variables//////////////////////////

    //Create a EVEN N variable between 10 and 30
    
    int N = (int)(Math.random()*20)+10;
    N = (N*2)%30;
    //Create a simple linkedlist with N nodes
    LC e1 = new LC();
    LC tete = null;
    while(N!=0) {
        if(e1==null) {
            e1 = new LC();
            tete = e1;
            e1.data = N;
            
        }
        else {
            e1.suiv = new LC();
            e1.suiv.data = N;
            e1 = e1.suiv;
        }
        N = (int)(Math.random()*20)+10;
        int M = (int)(Math.random()*-20)-10;
    }

Ответы [ 2 ]

3 голосов
/ 02 августа 2020

У вас есть два варианта:

  1. Сначала «подбросьте монету», чтобы решить, положительно или отрицательно, затем сгенерируйте -10 / -30 или 10/30 в зависимости от подбрасывания монеты.
  2. Сгенерируйте случайное число в диапазоне [0,40] и сопоставьте его с вашим фактическим желаемым диапазоном.

Обратите внимание, что # 1 проблематично c, если 2 диапазона не совпадают. t одинакового размера, если вы хотите равномерного случайного распределения.

В качестве отдельного примечания, Math.random() * 20 неверно.

По сути, в порядке математического доказательства:

  1. a double in java имеет 64 бита. Это означает, что он может представлять не более 2 ^ 64 чисел. Это МНОГО чисел, но не бесконечное их количество.
  2. ... и только некоторые из этих чисел находятся между 0 (включительно) и 1 (исключая). Допустим, их 1000005.
  3. Учитывая, что это ровно 10000005 из них, и каждое последнее из этих 10000005 чисел будет «отображаться» на одно из ваших чисел, которые имеют общий «диапазон» 20 ( или 40, не имеет значения), ну, 40 не идеально подходит для 10000005.
  4. Таким образом, я доказал, что некоторые числа будут встречаться чаще, чем другие, и ваш результат не является действительно случайным. QED.

Решение состоит в том, чтобы создать экземпляр Random и использовать его метод .nextInt(20), который IS действительно равномерно распределен.

Метод подбрасывания монет

Random r = new Random(); // make one instance, once, in your app.
boolean goNegative = r.nextBoolean();
int nr = (goNegative ? -1 : +1) * (10 + r.nextInt(20));
// note, like in your example, 10 is possible,
//but 30 cannot be hit. Make it r.nextInt(21)
//instead if it needs to be.

Метод сопоставления

Random r = new Random(); // make one instance, once, in your app.
int nr = r.nextInt(40);
if (nr < 20) nr -= 29; // all numbers from -29 to -10, inclusive, covered.
else nr -= 10; // covers 10-29 inclusive.
2 голосов
/ 02 августа 2020

Попробуйте следующее:

Random r = new Random();
// the following generates a number between 0 and 20 inclusive and adds 10 to it
int a = r.nextInt(21)+10; // between 10 and 30 inclusive

// the following does the same but changes the sign.
int b = -(r.nextInt(21)+10); // between -10 and -30 inclusive

For the negative one you could also do this.
b = -30+r.nextInt(21);

Итак, если вы хотите случайным образом выбрать один из обоих наборов, вы можете сделать следующее:

int n = nextInt(2) == 0 ? -30+r.nextInt(21) : r.nextInt(21)+10;
...