java 中具有不同出现规则的随机数从一个数组到另一个数组

random numbers from an array into another array with different occurences rules in java

我在学校做运动需要帮助。

我需要使用以下数组中的 6 个随机整数创建一个数组:montab[] = {1,2,3,4,5,6,7,8,9,10,25,50,75,100} 并遵循以下规则:

  1. 数字25,50,75,100在数组中每个只能出现一次
  2. 数字110在数组中每个只能出现两次

我现在尝试了第一个规则,但在极少数情况下,我仍然不止一次得到这个数字。

这是我的代码:

public class Exo7bis {
public static void main (String[] args){
    Random random = new Random();
    int montab[] = {1,2,3,4,5,6,7,8,9,10,25,50,75,100};
    int[] ar1 = new int[6];
    int j = 0, compteur25 = 0, compteur50 = 0, compteur75 = 0, compteur100 = 0;
        for (int i = 0; i < ar1.length; i++) {
            ar1[i] = (montab[new Random().nextInt(montab.length)]);
            if (ar1[i] == 25) {
                compteur25++;
                if (compteur25 > 1) {
                    while (ar1[i] == 25)
                        ar1[i] = (montab[new Random().nextInt(montab.length)]);
                }
            }
            if (ar1[i] == 50) {
                compteur50++;
                if (compteur50 > 1) {
                    while (ar1[i] == 50)
                        ar1[i] = (montab[new Random().nextInt(montab.length)]);
                }
            }
            if (ar1[i] == 75) {
                compteur75++;
                if (compteur75 > 1) {
                    while (ar1[i] == 75)
                        ar1[i] = (montab[new Random().nextInt(montab.length)]);
                }
            }
            if (ar1[i] == 100) {
                compteur100++;
                if (compteur100 > 1) {
                    while (ar1[i] == 100)
                        ar1[i] = (montab[new Random().nextInt(montab.length)]);
                }
            }
        }

        for (int i = 0; i < ar1.length; i++) {
            System.out.print(ar1[i] +" ⎢ " + "\t");
        }
    }
}

我知道我的测试并不完全正确,我发现了问题,但我找不到合适的解决方案。

如果有人能帮助我或给我建议,那就太好了。

提前致谢!

杰里米

实际上有一个简单的解决方案,尽管它不能保证真正个随机数。

我们要做的是创建一个数组,其中数字 1 - 10 列出两次,25 - 100 列出一次。每次选择一个数字时,我们将其替换为 0。

因此,不可能选择超过一个 25 或超过两个 8。

在代码中,

public class Exo7bis {

    public static void main (String[] args){

        Random random = new Random();

        int[] intPool = {1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,25,50,75,100};
        int[] chosen = {0,0,0,0,0,0};

        int counter = 0;

        // while the list is not full
        while (chosen[5] == 0) {

            // generate a number from 0 - 23 (representing the numbers in intPool)
            int temp = random.randInt(24);

            // if that element in intPool = 0, it means that it's already chosen
            // and can't be chosen again.
            if (intPool[temp] != 0) {
                chosen[counter] = intPool[temp];
                intPool[temp] = 0;

                counter++;
            }
        }
    }
}

有很多方法可以实现这一点,但由于您只是使用数组,我建议您制作一个函数来计算 1-10 重复了多少次。对于第一个条件,您可以将元素替换为 0 这样下次就不会重复了。我认为用代码很容易解释,所以看看您可以在代码中更改什么:

public static void main(String[] args) {
        Random random = new Random();
        int montab[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 25, 50, 75, 100 };
        int[] ar1 = new int[6];
        int j = 0, count = 0;
        while (j < ar1.length) {
            count = 0;
            int index = random.nextInt(montab.length);
            int num = montab[index];
            if (num >= 25) { //adds any number greater or equal to 25
                ar1[j] = num;
                j++;
                montab[index] = 0; // replace the origianl array with 0.
            } else if (num != 0) {
                if(!isRepeated(ar1,num)){ //checks if the array has more than two of the number.
                ar1[j] = num;
                j++;
                }
            }
        }
        for (int i = 0; i < ar1.length; i++) {
            System.out.print(ar1[i] + " ⎢ " + "\t");
        }
    }

    public static boolean isRepeated(int[] arr, int num) { //method that verifies if the array has a number repeated twice or not.
        int count = 0;
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == num)
                count++;
        }
        return count==2 ? true : false;
    }

我还没有测试过,但我很确定它会起作用!!

这是我的方法。我试着修改原来的list/array,这样如果按照规则使用,原始数字的大小就会缩小。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

public class Exo7bis {
    private static final List<Integer> montab = new ArrayList<Integer>(Arrays.asList(new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 25, 50, 75, 100 }));
    private static final List<Integer> allowOnce = new ArrayList<Integer>(Arrays.asList(new Integer[] { 25, 50, 75, 100 }));
    private static final List<Integer> allowTwice = new ArrayList<Integer>(Arrays.asList(new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }));
    public static void main(String[] args) {
        int[] ar1 = new int[6];
        for (int i = 0; i < ar1.length; ++i) {
            int index = new Random().nextInt(montab.size());
            int value = montab.get(index);
            ar1[i] = value;
            if (isOneOff(value)) {
                montab.remove(index);
            } else if (isTwoOff(value))
                montab.remove(index);
        }
        System.out.println(Arrays.toString(ar1));
    }
    public static boolean isOneOff(final int n) {
        for (int i = 0; i < allowOnce.size(); ++i)
            if (allowOnce.get(i) == n)
                return true;
        return false;
    }
    public static boolean isTwoOff(final int n) {
        boolean one = false, two = false;
        for (int i = 0; i < allowTwice.size(); ++i) {
            int j = 0;
            for ( ; j < montab.size(); ++j) {
                if (montab.get(j) == n) {
                    one = true;
                    break;
                }
            }
            ++j;
            for ( ; j < montab.size(); ++j) {
                if (montab.get(j) == n) {
                    two = true;
                    break;
                }
            }
        }
        return (one && two);
    }
}

这是一个仅涉及数组并提供您想要的随机性的解决方案。这个想法是将所选值的出现存储在另一个 int[] 数组中,并将它们与您的限制进行比较。 [底部的完整代码]

说明

if ((randomNum < 25 && newOccurence == 2) || randomNum >= 25)

检查您的最大出现次数。

然后,您重新创建没有达到其限制的值的原始数组 (montab)。

int[] tempTab = new int[montab.length - 1];
int skips = 0;
for (int j = 0; j < tempTab.length; j++) {
    if (montab[j] == randomNum) {
        skips++;
    }
    tempTab[j] = montab[j + skips];
}
montab = tempTab;

如果原始数组中没有重复值,这种方法显然有效。由于数组的重建,性能可能不是最好的,但至少你避免了可能一遍又一遍地达到相同值的随机性。

测试代码

import java.util.Random;

public class Exo7bis {

    public static void main (String[] args){

        int[] montab = {1,2,3,4,5,6,7,8,9,10,25,50,75,100};
        int[] ar1 = new int[6];
        int[] occurences = new int[montab.length];

        for (int i = 0; i < ar1.length; i++) {

            int randomIndex = new Random().nextInt(montab.length);
            int randomNum = montab[randomIndex];
            int newOccurence = (occurences[randomIndex] = occurences[randomIndex] + 1);

            /*  UNCOMMENT THIS FOR VISUAL STEPS
            for (int a : montab) { System.out.print(a + " | "); }
            System.out.println("");
            */

            if ((randomNum < 25 && newOccurence == 2) || randomNum >= 25) 
            { 
                int[] tempTab = new int[montab.length - 1];
                int skips = 0;
                for (int j = 0; j < tempTab.length; j++) {
                    if (montab[j] == randomNum) {
                        skips++;
                    }

                    tempTab[j] = montab[j + skips];
                }
                montab = tempTab;
            }
            ar1[i] = randomNum;
        }

        for (int i = 0; i < ar1.length; i++) {
            System.out.print(ar1[i] +" |" + "\t");
        }
    }
}