我正在尝试编写一个程序,它由一个数组组成,填充50个随机数,介于值1-999之间。但是,在将一个随机数添加到数组之前,我必须检查该数字是否重复,并且不在数组中。
我似乎非常接近正确的输出,但是由于某种原因,我反复得到数字0作为我的数组中的第一个元素,它也是唯一重复的数字。有谁知道这是为什么,如果能够提供合适的解决方案?
找到副本后,需要将其打印到输出中,并替换为新的唯一随机数。
提前致谢。
import java.util.*;
public class Random50 {
public static void main (String[] args)
{
final int MAX_SIZE = 50;
int[] r50 = new int[MAX_SIZE];
boolean duplicates = false;
Random rand = new Random();
for (int i=0; i<r50.length; i++)
{
for (int j=i+1;j<r50.length;j++)
{
r50[i] = rand.nextInt(1000);
if (j!=i && r50[i] == r50[j])
{
duplicates = true;
System.out.println("DUPE: " + r50[i]);
r50[i] = rand.nextInt(1000);
}
}
}
System.out.println(Arrays.toString(r50));
}
}
答案 0 :(得分:1)
j总是大于i,因为你将j初始化为i + 1。这意味着j引用的r50值始终为0,因此这些值将始终为重复值。
例如,如果i = 20,在第二个循环中,j将从21开始.r50 [21],r50 [22]等等都是0,因为你还没有设置它们,所以r50 [i]和r50 [j]唯一可能的副本是0。
编辑:如果j的点是遍历数组的所有先前元素,那么你将需要
for (int i=0; i<r50.length; i++)
{
r50[i] = rand.nextInt(1000); //Set it before the j loop
for (int j = 0; j < i; j++)
{
while (r50[i] == r50[j]) //while loop, in case of multiple duplicates
{
duplicates = true; //Still not sure why you want this boolean
System.out.println("DUPE: " + r50[i]);
r50[i] = rand.nextInt(1000);
}
}
}
虽然这仍然无法完美运行,因为您可能会在检查后将r50设置为较早的值。例如,如果你确定r50 [20]不等于j到10的任何值,然后它等于r50 [11](当j = 11时),那么你可能会意外地将它改回到a j的值小于该值(例如,r50 [5])。
我认为最好的方式是,正如Duncan和Rajeev所做的那样,
HashSet numbers = new HashSet();
Random rand = new Random();
while(numbers.size() < MAX_SIZE) {
numbers.add(rand.nextInt(1000));
}
答案 1 :(得分:0)
性能方面,每次将值与数组的下一个位置进行比较时,这都不是一个好方法。您应该使用散列算法,根据其唯一的哈希码,您可以知道对象可能位于哪个位置。这里进入图片HashSet
,对于大多数操作都有O(1),这在Integer
类对象中很少有哈希码冲突的可能性
public static void main (String[] args)
{
final int MAX_SIZE = 50;
HashSet<Integer> hs = new HashSet<Integer>(50);
while(hs.size()<50){
Random rand = new Random();
int randomVal = rand.nextInt(1000);
hs.add(randomVal);
}
Integer[] r50 = hs.toArray();
}