生成一个包含唯一随机整数的数组,检查是否存在重复。

3
这是一份我即将完成的学校作业,但我还没有完全掌握。我应该生成一个整数节点数组,其中包含100个随机数字,且不重复,通过检查重复来实现。 我不能使用Set。 我不能只是打乱1-1000的数字数组。
这是我在客户端类中目前拥有的代码,但它仍然会创建重复项:
for (int i = 0; i < SIZE; i++) {
    int j = (int)(Math.random()*1999);

 //put a random number in the first index.
    if (i == 0) {
        Node newNode = new Node(j);
        nodeArray[i] = newNode;
    }

    for (int k = 0; k < i; k++) {
        if (nodeArray[k].getInt() == j) {
            j = (int)(Math.random()*1999);
            break;
        } else {
            Node newNode = new Node(j);
            nodeArray[i] = newNode;
        }
    }
}

1
如果您发现重复项,仅选择一个新数字是不够的。您还必须检查新数字,因为它也可能是重复项。基本上,在索引i处,持续生成随机数,直到找到一个未在位置0..i-1上使用的数字。找到后,分配给索引i并重复i + 1。 - Roger Lindsjö
@RogerLindsjö 那我把最内层的if语句改成while,这样能修复它吗? - Maggie S.
@MagdaleneB。请检查我的答案,它很容易理解。 - Juvanis
4个回答

2
我会这样做:使用一个列表来存储所有的随机数字。当你生成一个数字时,你可以检查它是否已经存在于列表中,如果存在就再生成一个数字(通过递归或while循环完成)。一直这样做直到列表满了为止。然后遍历列表创建数组的节点。
List<Integer> numbers = new ArrayList<Integer>(SIZE);
for (int i = 0;i<SIZE; i++) {
    addUniqueRandomNumber(numbers, SIZE*2);
}

for (int i =0;i<numbers.size; i++) {
  Node newNode = new Node(numbers.get(i));        
  nodeArray[i] = newNode;
}

addUniqueRandomNumber方法:

public static void addUniqueRandomNumber(List<Integer> numbers, int range) {
    int j = (int)(Math.random()*range);
    if (numbers.contains(j)) {
        addUniqueRandomNumber(numbers, range);
    } else {
        numbers.add(j);
    }
}

1

因为当你在分配一个新的随机数时,如果第一个随机数是重复的,在第二个if语句中它永远不会检查该随机数是否也可能是重复的。你需要重新执行循环并检查该数字是否也是重复的。

for (int k = 0; k < i; k++) {
    if (nodeArray[k].getInt() == j) {
        j = (int)(Math.random()*1999); //You must check if this random is also a dup
        break;
    } else {
        Node newNode = new Node(j);
        nodeArray[i] = newNode;
    }

这是我会做的事情:

int i = 0;
while (i < SIZE) {
int j = (int)(Math.random()*1999);

 //put a random number in the first index.
if (i == 0) {
    Node newNode = new Node(j);
    nodeArray[i] = newNode;
    i++;
}

for (int k = 0; k < i; k++) {
    if (nodeArray[k].getInt() == j) {
        //Do nothing
    } else {
        Node newNode = new Node(j);
        nodeArray[i] = newNode;
        i++;
    }
  }
}

基本上只有在数字不重复时才会增加i,否则请继续查找其他不重复的随机数。


1
我建议使用一个辅助布尔数组来跟踪已添加到数组中的数字。请查看此代码,它简短而简洁:
boolean[] used = new boolean[2000];
int[] randomUniqueIntegers = new int[SIZE];

for (int i = 0; i < SIZE; i++) {
    int num = (int) (Math.random() * 1999);

    if (!used[num]) {
        used[num] = true;
        randomUniqueIntegers[i] = num;
    } else {
        while (used[num]) {
            num = (int) (Math.random() * 1999);
            if (!used[num]) {
                used[num] = true;
                randomUniqueIntegers[i] = num;
                break;
            }
        }
    }
}

正如您所见,上面的实现没有使用Set或洗牌。但是,您可以使用下面的测试代码来查看它是否正常工作。

Set<Integer> set = new HashSet<Integer>();
for (int i : randomUniqueIntegers)
    set.add(i);
System.out.println(set.size());

你会发现在每次运行中,集合的大小都等于SIZE常量,这表明我们的数组中有所有唯一的元素。

while (used[num]) 迭代的是什么? - jrowe08
@jrowe08 它不会迭代某个东西,它只是尝试找到一个未使用的整数,当找到时,while循环就会终止。 - Juvanis

1

检查每个生成的数字是否存在于解算法中:

int[] nodeArray = new int[100];
int currentIndex = 0;

while(currentIndex < 100) {
    int currentValue = (int) (Math.random() * 199);
    int i = 0;
    while(i < currentIndex) {
        if(currentValue == nodeArray[i]) {
            break;
        }
        i++;
    }
    if(i == currentIndex) {
        nodeArray[currentIndex++] = currentValue;
    }
}

然后你可以对随机数进行排序并打印。
Arrays.sort(nodeArray); // Sort to be easy find duplicates
for (Integer i : nodeArray) {
    System.out.print(i + ", ");
}

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