0

我有一个作业要编写一个返回 1 到 54 之间的随机数的方法,不包括参数中传递的数字。方法头指定如下:

public static int getRandom(int... numbers)

我不能使用比一维数组更高级的东西。

我的代码是:

public class PE13RandomNumberChooserVer2 {

    public static void main(String[] args) {

        int[] excludeNumbers = {1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 13, 14, 15, 16, 17, 18};
        int randomNumber = getRandom(excludeNumbers);
        System.out.println();
        System.out.println("Random number chosen: " + randomNumber);
    }

    public static int getRandom(int... excludeNumbers) {

        int random = 1 + (int)(Math.random() * (54 - 1) + 1);
        System.out.println("Numbers to exclude: ");

        for (int i = 0; i < excludeNumbers.length; i++) {
            System.out.print(excludeNumbers[i] + " ");
            while (excludeNumbers[i] == random) {
                random = 1 + (int)(Math.random() * 54);
                System.out.println("\n(for test only) next random number: " + random);
            }
        }

        return random;
    }

}

示例运行表明我的逻辑是错误的:

(for test only) initial random number: 8
Numbers to exclude: 
1 2 3 4 5 6 7 8 
(for test only) next random number: 12
11 12 
(for test only) next random number: 3
13 14 15 16 17 18 
Random number chosen: 3

它仅检查 random 是否等于数组中的当前项目,它不考虑它可以等于列表中已检查的前一个项目的情况。

随机生成的数字的最终结果应该是与数组中的数字不同的值。非常感谢任何如何解决它的建议。

4

8 回答 8

4

以下将做到这一点:

    private final Random rand = new Random();

    public int getRandom(int min, int max, int... excludeNumbers) {
        int random = rand.nextInt(max - min + 1 - excludeNumbers.length) + min;
        for (int exc : excludeNumbers) {
            if (random >= exc) {
                random++;
            }
        }
        return random;
    }

观察它如何只生成一个随机数并且不需要拒绝循环。

请注意,两者minmax包括在内。还要注意excludeNumbers必须按升序出现。

于 2012-12-16T19:26:36.690 回答
3

int random = 1 + (int)(Math.random() * (54 - 1) + 1);

还有这个

random = 1 + (int)(Math.random() * 54);

很奇怪,应该重合。

后一种是正确的。

接下来你的循环是错误的。循环用于重新生成号码,以防它与禁止号码重合。所以你应该把所有的循环都放在for里面while,然后放在外面。应该用于检查生成的所有禁止号码,并且应该作为检索循环服务。printlnforwhile

您也可以使用Random 类

编码

public static void main(String[] args) {

        int[] excludeNumbers = {1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 13, 14, 15, 16, 17, 18};
        int randomNumber;

        System.out.println("Numbers to exclude: ");
        for (int i = 0; i < excludeNumbers.length; i++) {
            System.out.print(excludeNumbers[i] + " ");
        }


        // 100 tests
        for(int i=0; i<100; ++i ) {


            randomNumber = getRandom(excludeNumbers);
            System.out.println();
            System.out.println("Random number chosen: " + randomNumber);
        }
    }

    public static int getRandom(int... excludeNumbers) {

        int random;



        // regeneration loop 
        regeneration: while(true) {

            // generating a number
            random = 1 + (int)(Math.random() * 54);

            // checking of it's correctness
            for (int i = 0; i < excludeNumbers.length; i++) {

                // checking if number conincides for prohibited
                if( excludeNumbers[i] == random ) {

                    // if number concided, then going to regeneration
                    continue regeneration;
                }

                // here number has not coincided 
                // but with just one of prohibites
                // no decision here
            }

            // here all prohibited numbers checked and 
            // no coincidences found
            // so generated number is good

            System.out.println("\n(for test only) next random number: " + random);
            break regeneration;

        } 

        return random;
    }
于 2012-12-16T19:07:39.230 回答
1

试试这个,它只是不断尝试,直到你得到一个可以接受的数字。

List<Integer> nums = Arrays.asList(excludedNumbers);
while (true) {
    Random random = 1 + (int)(Math.random() * 54);
    if (!nums.contains(random))
        return random;
}

如果您将排除数字作为列表传递,该方法会更简洁。

于 2012-12-16T19:06:14.540 回答
1

不断重试直到达到允许的数字的技术是粗糙的,并且随着允许的数字的数量接近 1 变成一个哭泣的痛苦。一个更优雅的方式是这样的:

  1. 创建一个boolean[54]
  2. 将每个排除的元素设置为true;
  3. 从与允许选择的数量一样大的范围中选择一个随机数r(54 - 排除数);
  4. 返回布尔数组中的第 r 个假元素。

boolean注意:当你可以缓存数组时,这个算法是最合适的;对于您的确切情况(该函数每次都会接收一个新数组)NPE 的解决方案是优越的。

于 2012-12-16T19:27:51.117 回答
0

查看 java.util.random,它有一个方法可以提供 0 和您指定的数字之间的随机整数。我不能给你一个例子,因为我现在正在用我的手机输入这个,但如果你要在 1 到 54 之间得到它,我会得到一个 0 到 53 之间的随机数并将结果加 1。

于 2012-12-16T20:35:37.857 回答
0

我现在也在自学Java。我已经在这个问题上花了几天时间,而网上还没有答案。到目前为止,上述解决方案对我来说太先进了。这是我最后的解决方案,它只使用基本的数组知识

    public class Q6_13 {
    public static void main(String[] args)  {
        int[] excludeNumbers = {1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 13, 14, 15, 16, 17, 18};
        System.out.println (getRandom(excludeNumbers));
    }

    public static int getRandom(int...numbers)  {
        int n =  (int)(Math.random() * 54) + 1; ;
        boolean newRandom = false;
        boolean getNew = false;

         while (getNew == false)   {
        for (int i = 0; (i < numbers.length) && newRandom == false; i++)    {
            if (n == numbers[i])    {
                newRandom = true;                 
            }
        }
            if (newRandom)  {
                n = (int)(Math.random() * 54) + 1; 
                getNew = false;
                newRandom = false;
            }
            else
                getNew = true;
        }
        return n;
    }
}
于 2013-04-01T19:18:14.980 回答
0
public static int getRandom(int... numbers) {
    final Random random = new Random();
    final int[] arr1 = new int[54];
    int count = 54;
    for(int i = 0; i < arr1.length; ++i) {
        arr1[i] = i + 1; // good luck doing this with foreach
    }
    for(int i = 0; i < numbers.length; ++i) {
        final int n = numbers[i];
        if(arr1[n] != 0) {
            --count;
        }
        arr1[n] = 0;
    }
    final int[] arr2 = new int[count];
    for(int i = 0, j = 0; i < arr2.length; ++i, ++j) {
        if(arr1[j] == 0) {
            ++j;
        }
        else {
            arr2[i] = arr1[j];
        }
    }
    return arr2[random.nextInt(count)];
}
于 2015-08-01T13:34:36.473 回答
0

公共类计算{

public static void main(String[] args) {
    int[] values = {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41};
    int x = 1+ (int) (Math.random()*54);
    System.out.println("Value: "+getRandom(x,values));  
}

public static int getRandom(int a, int... numbers){

    System.out.println("x1: "+a);
    for(int j=0;j<numbers.length;){
        //System.out.println("Numbers: "+numbers[j]);
        if(numbers[j]==a){
            a = 1 + (int) (Math.random()*54);
            System.out.println("x2: "+a);
            j=0;
            continue;
        }
        j++;
    }
    return a;

}

}

于 2015-08-21T06:41:43.017 回答