在将重复项添加到数组之前识别它们。

3
我正在尝试编写一个程序,它包括一个长度为50的数组,其中填充有1-999之间的50个随机数。然而,在向数组添加随机数之前,我必须检查该数字是否重复,且该数字是否已存在于数组中。
我似乎已经非常接近正确的输出结果了,但由于某种原因,我的数组中第一个元素总是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));
}

}


在找到重复项后,您没有取消设置“duplicates”。 - Kevin L
你为什么不能使用集合呢? Collection 对象有一个 .contains() 方法。 - Patrick J Abare II
2
如果您需要保留非重复项,可以使用 Set<Integer>。然后,您的代码可能会非常简单 - 循环,将值添加到集合中,直到它有50个元素。 - Duncan Jones
遵循 Set 的建议可能是最好的选择,但在 if (j!=i && r50[i] == r50[j]) 之后对你的代码进行评论不能保证获得一个不重复的数字。使用 while 来解决这个问题。 - Eypros
2个回答

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时),则您可能会意外地将其更改回小于该值的j的值(例如,r50 [5])。
我认为最简洁的方法是像Duncan和Rajeev一样。
HashSet numbers = new HashSet();
Random rand = new Random();

while(numbers.size() < MAX_SIZE) {
    numbers.add(rand.nextInt(1000));
}

我明白你的意思了,我之前没有考虑到这一点!这是否意味着我应该将j初始化为i? - freshwaterjoe
说实话,我不确定 j 的意义是什么。你是想检查之前没有添加其他值吗?如果是这样,你需要让 j 从0开始,但要增加到i。但最好的答案是Rajeev的,带有我的编辑。 - Sherz

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();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接