随机选择2D阵列中的唯一元素

时间:2012-10-21 19:45:05

标签: java algorithm

嗨,所以我正在做一项任务,但我对2D阵列的概念不太满意。我正在编写一个随机选择2D数组中元素的方法体。但是,我不确定何时如何处理这个问题。

我在考虑使用随机数生成器来选择随机元素。虽然我首先需要的是首先用一个值来填充盒子的整个长度。在这种情况下,2D阵列框的尺寸为20x20,值为零。所以我希望2D数组完全用零填充。虽然如果我使用随机数生成器,是否有可能在整个盒子尺寸首先用零填充之前,可能会再次使用生成器随机选择的元素?

很抱歉长文本块。基本上我要问的是,是否有办法使用随机数生成器仍然随机生成数字但不重复以前使用过的数字。

4 个答案:

答案 0 :(得分: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 :(得分: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];
         }

答案 2 :(得分:0)

根据我上面的内容...你想要用0填充20x20 2D数组,但是你想通过每次在数组中选择一个随机位置来做到这一点,而你不想“重新填充” “一个插槽。

执行此操作的最快方法是创建一个包含所有可能位置的数组(在这种情况下,如果您认为值/ 20 =第一个索引,则值为0..399,值为%20 =第二个index,例如125 = array [125/20] [125%20]或array [6] [5],参见?)

因此,首先,使用值0..399填充此数组位置[400]。

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

然后,从399的上限开始,生成从0到上限的随机数loc,并使用位置[loc]作为当前索引填充0,然后将位置[loc]与位置交换[cap] ],将上限减少1,然后继续。当上限达到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的边界之外。下一次循环,再次选择该值(或已经使用的任何其他值)是不可能的。

答案 3 :(得分:0)

在填充数组时,你可以让一个arraylist来添加每个单元格的索引(比如i,j),然后生成随机数

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];