对于Loop 2D阵列

时间:2016-08-10 09:14:59

标签: java arrays loops 2d

在这个程序中,我想用三个O来替换随机位置的三个N.我尝试使用forloop来实现这一目标,但是,' O'我得到的是不一致的。我不确定哪个部分出了问题......

static char grid[][];
public static void Board()
{
    Random rn = new Random();
    grid = new char [3][3];
    for(int row = 0; row<grid.length; row++)
    {
        for(int col = 0; col<grid.length; col++)
        {
        grid[row][col] = 'N';     
            for(int i = 0; i<3; i++)
            {
            grid[rn.nextInt(3)][rn.nextInt(3)] = 'O';  
            }
        System.out.print(grid[row][col]);   
        }
        System.out.println();
    }       
}

4 个答案:

答案 0 :(得分:2)

你需要分开你的循环。

首先用N s初始化数组,然后替换3 N s:

for(int row = 0; row<grid.length; row++) {
    for(int col = 0; col<grid[row].length; col++) {
        grid[row][col] = 'N'; 
    }
}
for(int i = 0; i<3; i++) {
    grid[rn.nextInt(3)][rn.nextInt(3)] = 'O';  
}

在内部初始化循环中运行for(int i = 0; i<3; i++)会导致3个随机单元格被分配O 3x3次,之后可以用N覆盖这些单元格,因为您之前正在执行此操作初始化完成。

您还应该注意,grid[rn.nextInt(3)][rn.nextInt(3)] = 'O'分配的单元格可能不是3个唯一单元格,因此您最终可能会少于3 O s。

您可以使用while循环替换第二个循环,以确保更换正好3个单元格:

int i = 0;
while(i < 3) {
    int x = rn.nextInt(3);
    int y = rn.nextInt(3);
    if (grid[x][y] != 'O') {
        grid[x][y] = 'O';
        i++;
    }  
}

答案 1 :(得分:1)

有时候一点抽象会让事情变得更容易。

为什么你的循环内有随机内容?您的约束是您希望九个数组索引中的三个完全不同。因此:不要迭代数组并在那里调用随机函数。

只需创建(0,8)范围内的随机数,直到得到三个不同的值;然后更新数组中的相应索引。

你知道,棘手的部分是关于正好三个;这可以通过以下代码实现:

Set<Integer> randomIndexesToChange = new HashSet<>();
while (randomIndexesToChange.size() < 3) {
 randomIndexesToChange.put( ... another random number from (0, 8) );
}

或者像RealSceptic建议的那样,创建一个集合对象,它只包含0到8之间的所有索引;然后你使用shuffle;然后选择前三个:

List<Integer> allIndexes = Arrays.asList(0, 1, ...
Collections.shuffle(allIndexes);
// now allIndexes is in random order
// so allIndexes.get(0) gives you the first index that should be O

...

答案 2 :(得分:0)

使用3个随机O填充网格的另一种方法是在初始化时立即执行:

int numOs = 3; 
for(int row = 0; row<grid.length; row++) {
  for(int col = 0; col<grid[row].length; col++) {
    if( numOs > 0 && randomConditionForO() ) {
       grid[row][col] = 'O'; 
       numOs--;
    } else {
       grid[row][col] = 'N';
    }
  }
}

randomConditionForO()可能类似于rn.nextInt() % 2 == 0等。如果您想提供设置O的概率,让我们说25%,您可以使用rn.nextInt(100) < 25之类的内容或rn.nextFloat() < 0.25f

然而,这里的问题是,由于条件的随机性,你可能会得到少于3个Os,所以你可能想要反击。一种方法可能是为Ns提供计数并相应地增加O的概率。

示例:

int numOs = 3;
int numNs = gridSize - numOs; //gridSize would be 3x3 = 9 in your example 
for(int row = 0; row<grid.length; row++) {
  for(int col = 0; col<grid[row].length; col++) {
    if( numOs > 0 && rn.nextInt(numNs + 1) < numOs ) {
       grid[row][col] = 'O'; 
       numOs--;
    } else {
       grid[row][col] = 'N';
       numNs--;
    }
  }
}

这里rn.nextInt(numNs + 1) < numOs意味着选择O的概率随着每个选择的N而增加,并且随着每个选择的O减少。因为nextInt(bound)将返回0(包括)和{{1}之间的整数}(独占)我们需要传入bound,这样如果没有更多的Ns可用,我们使用绑定1,因为它是独占的,我们总是得到0,小于{{1}只要有可用的Os(因此获得100%的概率)。

答案 3 :(得分:-1)

以@GhostCats为基础回答:

static char grid[][];
public static void Board()
{
    int width=3, height=3;

    // create new array filled with 'N'
    grid = new char [width][height];
    for(char[] col: grid)
        Arrays.fill(col, 'N');

    // create list of all possible indexes
    List<Integer> index = IntStream.range(0,width*height).boxed()
                                     .collect(Collectors.asList());
    Collections.shuffle(index);

    // replace first three indexes with 'O'
    for(int i=0; i<3; i++)
        grid[index.get(i)/width][index.get(i)%width] = 'O';    
}

需要Java 8。