Java 生成两个随机整数,并将其从再次生成中移除

Java 生成两个随机整数,并将其从再次生成中移除,java,Java,我有一个汽车对象的ArrayList,我想随机选择其中两个并比较它们。一旦我们对它们进行比较,我希望次等车不再被随机挑选。我认为我们无法阻止特定数字的产生,所以我想到了其他一些想法 以下是我一直在思考的一些事情: Idea 1: Include a "seen" attribute for each Car, set to false. Generate two random integers from 0 to size of Car List. Check to make sure two

我有一个汽车对象的ArrayList,我想随机选择其中两个并比较它们。一旦我们对它们进行比较,我希望次等车不再被随机挑选。我认为我们无法阻止特定数字的产生,所以我想到了其他一些想法

以下是我一直在思考的一些事情:

Idea 1:
Include a "seen" attribute for each Car, set to false.
Generate two random integers from 0 to size of Car List.
Check to make sure two indexes are not seen.
Check to make sure that two integers are not the same, if they are, regenerate and repeat.
Grab cars using the two indexes generated. 
If not seen, compare and flag the inferior as seen. 
If seen, store that cars index in a seenIndex array.

Idea 2:
Create a copy (would a deep copy be required here, im thinking no?) of the list of Cars.
Generate two random numbers, confirm they're not the same. 
Compare cars, remove the inferior car from the copyList.
Repeat.

我倾向于想法2,但如果有更优雅的解决方案,我很想听到。或者,您可以将随机生成的数字存储在arraylist中,然后每次生成新的随机数时,您可以首先检查数组,如果不包含,您可以选择它。你可以这样做:

public int generateRandomNumber(int start, int end, ArrayList<Integer> excludedNumbers) {
    Random rand = new Random();
    int range = end - start + 1;
    int random = rand.nextInt(range) + 1;
    while(excludedNumbers.contains(random)) { 
        random = rand.nextInt(range) + 1;
    }

    return random;
}

或者,您可以将随机生成的数字存储在arraylist中,然后每次生成新的随机数字时,您可以首先检查数组,如果不包含,则可以选择它。你可以这样做:

public int generateRandomNumber(int start, int end, ArrayList<Integer> excludedNumbers) {
    Random rand = new Random();
    int range = end - start + 1;
    int random = rand.nextInt(range) + 1;
    while(excludedNumbers.contains(random)) { 
        random = rand.nextInt(range) + 1;
    }

    return random;
}

你的想法2是一个非常简单的方法,我会推荐

唯一需要更改的是,copy arraylist不需要是深度副本。这是因为对于较便宜的浅拷贝,从一个列表中删除一个项目对另一个列表没有影响

你肯定不想像另一个答案所建议的那样,跟踪使用了哪些索引。
这就解释了为什么另一个答案是个坏主意。数学并没有直接转化为这个例子,因为除了上一次迭代之外,还有多个目标数字,但在成功之前仍有大量的预期尝试,特别是当你开始使用更大的汽车列表时。

我推荐你的想法2是一个非常简单的方法

唯一需要更改的是,copy arraylist不需要是深度副本。这是因为对于较便宜的浅拷贝,从一个列表中删除一个项目对另一个列表没有影响

你肯定不想像另一个答案所建议的那样,跟踪使用了哪些索引。
这就解释了为什么另一个答案是个坏主意。数学并不能直接转化为这个例子,因为除了上一次迭代之外,还有不止一个目标数字,但在成功之前,仍然有大量的预期尝试,特别是当你从更大的汽车列表开始时。

正如其他人所说,想法1,尽管它会起作用,对于一系列大小合适的汽车来说是不可行的

我会选择方案2

关于确认2个随机数不相同的一点,我建议您不要创建另一个随机数,而是这样做:

Random rnd = new Random()

int rand1 = rnd.nextInt(copyList.size() - 1); 
int rand2 = rnd.nextInt(copyList.size() - 2);

if(rand2 >= rand1) rand2++;
这避免了创建一个可能与您必须替换的随机数相同的随机数,并且会使您的程序更快

但是,如果您只是想找出哪辆车更好,您可以遍历一个数组或一系列汽车类别,将每个类别与当前最佳类别进行比较,其中汽车是一系列汽车,getPoints返回汽车的性能:

int bestIndex = 0;

// Loop starts at 1 b/c we don't need to compare index 0 w/ 0
// i.e. # of comparisons is 1 minus the # of Cars
for(int i = 1; i < cars.length - 1; i++){ 

    if(cars[i].getPoints() > cars[bestIndex].getPoints()){
        bestIndex = i;
    }

}

这将保留阵列并有效地找到最佳汽车。当然,这可以修改为一个列表。

正如其他人所说,想法1虽然可行,但对于一个相当大的汽车列表来说是不可行的

我会选择方案2

关于确认2个随机数不相同的一点,我建议您不要创建另一个随机数,而是这样做:

Random rnd = new Random()

int rand1 = rnd.nextInt(copyList.size() - 1); 
int rand2 = rnd.nextInt(copyList.size() - 2);

if(rand2 >= rand1) rand2++;
这避免了创建一个可能与您必须替换的随机数相同的随机数,并且会使您的程序更快

但是,如果您只是想找出哪辆车更好,您可以遍历一个数组或一系列汽车类别,将每个类别与当前最佳类别进行比较,其中汽车是一系列汽车,getPoints返回汽车的性能:

int bestIndex = 0;

// Loop starts at 1 b/c we don't need to compare index 0 w/ 0
// i.e. # of comparisons is 1 minus the # of Cars
for(int i = 1; i < cars.length - 1; i++){ 

    if(cars[i].getPoints() > cars[bestIndex].getPoints()){
        bestIndex = i;
    }

}
这将保留阵列并有效地找到最佳汽车。当然,可以对列表进行修改