在二维数组中随机选择一个唯一元素

3

嗨,我正在做一个作业,但是对于二维数组的概念有些困惑。我正在编写一个方法体,用于随机选择一个二维数组中的元素。然而,我不确定如何解决这个问题。

我考虑使用随机数生成器来选择一个随机元素。尽管我首先需要将整个盒子的长度用一个值填满。在这种情况下,二维数组盒子的尺寸为20x20,值为零。所以我希望二维数组完全被零填满。但是如果我使用随机数生成器,是否有可能在整个盒子尺寸被零填满之前再次使用随机数生成器随机选择的元素?

抱歉文字太长了。基本上我的问题是,是否有一种方法可以使用随机数生成器仍然随机生成数字,但不重复使用任何已经使用过的数字。


5
你可以创建一个包含0到19数字的数组,打乱顺序后遍历它。每次遍历都会得到一个独特的数字。 - Andrew Logvinov
2
请参考以下链接:http://stackoverflow.com/questions/3076147/how-to-generate-numbers-from-an-array-randomly-with-each-number-being-unique?rq=1 和 http://stackoverflow.com/questions/3095185/how-to-randomly-generate-a-unqiue-number-from-an-array-in-java?rq=1 - DNA
4个回答

3

一个选项是使用Collections.shuffle(allCells)

另一个选项是使用以下算法,通过跟踪剩余未使用的单元格:

1. Find a random number from 0 to size of the set - 1 .
2. Remove number at position `randomNumber` from the set.
3. Go to 1.

1
我会选择这个方向:
        int [][] myArray = new int[4][5]; //Any size and type
        int totalEmenent = myArray.length *myArray[0].length;
        int indexToSelect = (int)(Math.random()*totalEmenent);
        int xIndex = (int)indexToSelect/myArray.length;
        int yIndex = indexToSelect%myArray.length;
        int selectElement = myArray[xIndex][yIndex];

如果您希望每次选择唯一的索引:

        int [][] myArray = new int[4][5]; //Any size and type
        int totalEmenent = myArray.length *myArray[0].length;
        String selectedIndex = "";
        int numberOfSelect = 10; //Any number< totalEmenent

         for(int indx=0; indx< numberOfSelect; indx++){
              int indexToSelect = (int)(Math.random()*totalEmenent);
              //generate random until its unique
              while(selectedIndex.indexOf(String.valueOf(indexToSelect))> 0){
                   indexToSelect = (int)(Math.random()*totalEmenent);
              }
              selectedIndex = selectedIndex+indexToSelect;
              int xIndex = (int)indexToSelect/myArray.length;
              int yIndex = indexToSelect%myArray.length;
              int selectElement = myArray[xIndex][yIndex];
         }

随机选择一个唯一元素 - 如果这段代码被循环,它有可能会多次选择相同的元素。不是唯一的。 - Alex Lynch
我仍然不明白为什么你会想要“生成随机数直到唯一”...当你可以简单地确保它总是唯一的(见我的答案)。 - billjamesdev
@BillJames 在第一次运行中,随机值为5,5%400=5。在第二次运行中,如果仍然是5,则5%399=5。重复了。你的回答中是否有遗漏的内容? - Yogendra Singh
@Yogendra 是的,因为locations[5]中的值会随着第一次与locations[399]交换而改变,而这是在第一次选择时发生的。 - billjamesdev
@BillJames:明白了,谢谢你帮我理解你的回答 :) - Yogendra Singh
显示剩余2条评论

0

根据我上面读到的内容...你想用0填充一个20x20的二维数组,但是你想每次在数组中选择一个随机位置来填充,并且你不想“重新填充”一个槽。

最快的方法是创建一个包含所有可能位置的数组(在这种情况下,如果你认为值/20 = 第一个索引,值%20 = 第二个索引,例如125 = array [125/20] [125%20]或array [6] [5],那么就是0..399)

所以,首先用值0..399填充此数组locations [400]。

int [][] box = new int[20][20];
int [] locations = new int[400];
for ( int i = 0; i < 400; i++ ) locations[i] = i;

然后,从399开始,生成一个从0到cap的随机数loc,并使用locations[loc]作为当前索引来填充0,然后交换locations[loc]和locations[cap],将cap减1并继续。当cap达到0时,您将使用所有位置。

int cap = 399;
Random rand = new Random();
while ( cap >= 0 ) {
    int rnd = rand.nextInt(cap+1);
    int loc = locations[ rnd ];
    box[loc%20][loc/20] = 0;   // Here's where we set the value 0 into the 2D array
    // now swap the location selected with the value at the "end" of the current list.
    // hmm, forget the swapping, let's just bring that value in from the end.
    locations[rnd] = locations[cap];
    cap--;  // "shrink" the current list, eliminating the value we just put at the end from consideration.
}

应该就这样了。你应该能够看到,这个程序永远不会从“locations”数组中选择相同的值,因为循环末尾的交换将该位置的值放在了索引0到cap之外的边界上。下一次循环时,不可能再次选择该值(或任何其他已经使用过的值)。


1
rand.nextInt(); 会产生负值,并导致数组索引越界异常。 - Alex Lynch
好的,让我来修复一下。API 表示使用 nextInt(int arg) 会产生一个从 0 到 (arg-1) 的值,所以我将使用它。 - billjamesdev
我将我的交换操作更改为仅从“末尾”复制值到当前选择的位置,因为我不关心维护我再也不会使用的位置数组的部分。 - billjamesdev

-1

While populating your array, you can have an arraylist to add the index of each cell(say i,j), and then generate random number

Arraylist<int[]> ar=new Arraylist();
//inside loop for populating array
    yourArray[i][j]=whatever;
    ar.add({i,j});
//loop ends

int index=new Random().nextInt(ar.size());
int[] arrayIndex=ar.get(index);
ar.remove(index);
row=arrayIndex[0];
column=arrayIndex[1];
(Type)randomElement=yourArray[row][column];


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