我从java程序得到奇怪的输出

时间:2012-08-31 14:04:57

标签: java random

我在这里有一些奇怪的情况,我想你可以帮助我。我有一个int数组填充从1到10的数字。我想从这个数组生成随机数并将其保存到另一个int数组。我使用Random类来选择任何数字,因为随机抛出0我也会像那样修改它(所以它会抛出从1到10的数字)

randNum = rand.nextInt(numbers.length-min+1)+min;   

以下代码确保如果它生成相同的随机数,则会跳过它。程序实际上正在工作,我进入另一个数组,从1到10随机定位数字。这就是我想要的。但有时候我会错过1到10之间的一个数字而且我会改为ZERO。为什么??

int[] numbers = {1,2,3,4,5,6,7,8,9,10};
int[] usednum = new int[10];
Random rand = new Random();
int randNum;
int min = 1;

for (int x = 0; x<numbers.length; x++) {        
  for (int i = 0; i<usednum.length; i++) { 
    randNum = rand.nextInt(numbers.length-min+1) + min;
    for (int f = 0; f<usednum.length; f++) {
      if (usednum[f] == randNum) {
        break;
      } else if (usednum[f] == 0) { 
        usednum[x] = randNum;   
      }
    }
  } 
}

for (int c = 0; c<usednum.length; c++) {
  System.out.println(usednum[c]);
}

7 个答案:

答案 0 :(得分:2)

如果你的目标只是改变一系列数字,那就试试吧:

Integer[] numbers = {1,2,3,4,5,6,7,8,9,10};
Collections.shuffle(Arrays.asList(numbers));

它会产生同样的效果。除非您正在完成一项强制您以更加手动的方式解决问题的家庭作业,否则只需使用标准Java库。

shuffle方法将更改写入基础Integer数组,这要归功于List返回的特殊类型Arrays.asList(...)。请注意,您必须使用Integer而不是int的数组(请参阅Why does Collections.shuffle() fail for my array?)。

答案 1 :(得分:2)

您最内部for循环仅检查当前随机数是否在usednum[]数组中。紧靠其外的for循环仅检查总共10次。它放弃得太快,因为它只尝试10个随机数。如果已经使用了所有10个,那么usednum[]的那个插槽中不会存储任何内容(因此它将 0 ),尝试在其周围添加while循环并删除无关的外部for循环:

        for(int i = 0; i<usednum.length; i++) {
           while(usednum[i]==0) {
              randNum = rand.nextInt(numbers.length-min+1)+min;
              for(int f = 0; f<usednum.length; f++) {
                 if(usednum[f] == randNum) {
                    break;
                 } //if                                                                                                                                        
                 else if (usednum[f] == 0) {
                    usednum[i] = randNum;
                 }
              }
           }
        }

另请注意,作业适用于usednum[i] = randNum;

这实际上是用while循环替换中间for循环(从i = 0到9的循环)。

答案 2 :(得分:0)

编辑 - 跟着它并重新编写它:

List<Integer> numbers = new LinkedList<Integer>(Arrays.asList(new Integer[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }));
        int[] usednum = new int[10];
        Random rand = new Random();
        int n = numbers.size();
        for (int i = 0; i < n; i++) {
            int randNum = rand.nextInt(numbers.size());
            usednum[i]=numbers.get(randNum);
            numbers.remove(randNum);
        }
        for (int c:usednum) {
            System.out.println(c); 
        }

答案 3 :(得分:0)

您正在通过整个传递生成使用过的数字,因此它不会生成零,只是无法生成它应该的值。

答案 4 :(得分:0)

你有一个for循环太多了。

使用i迭代器删除循环,程序应该按照你想要的那样。

哦,从随机生成器中删除-min + 1,-1 + 1 = 0

答案 5 :(得分:0)

您的数组usednum在开头由零组成。在某些情况下,您的程序不会更改该初始值,但会在行之前中断:

if(usednum[f] == randNum)

并在具有相同值x的所有迭代期间执行此操作。 X递增,你有机会改变零值。

答案 6 :(得分:0)

实际上,您永远不会使用数组numbers的内容。尝试将数组更改为int[] numbers = { 10, 22, 23, 42, 53, 18, 7, 8, 93, 10 };之类的内容。你会得到类似的输出。

Jon Lin's answer描述了为什么您的代码无效但未解决此问题。我想您会想要将代码更改为:

    int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int[] usednum = new int[10];
    Random rand = new Random();

    int selectedCount = 0;

    while (selectedCount < numbers.length) {
        int randNum = numbers[rand.nextInt(numbers.length)];
        boolean contains = false;
        for (int x = 0; x < selectedCount; x++) {
            if (usednum[x] == randNum) {
                contains = true;
                break;
            }
        }

        if (!contains) {
            usednum[selectedCount] = randNum;
            selectedCount++;
        }
    }


    for (int c = 0; c < usednum.length; c++) {
        System.out.println(usednum[c]);
    }