For循环二维数组
For Loop 2D Array
在这个程序中,我想用三个 '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();
}
}
你需要分开循环。
先用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++;
}
}
有时一点点抽象会让事情变得容易得多。
为什么在你的循环中做随机的东西?您的约束是您希望九个数组索引中的三个“不同”。因此:不要迭代数组并在其中调用随机函数。
只需在 (0,8) 范围内创建随机数,直到获得三个不同的值;然后更新数组中的相应索引。
你看,棘手的部分是 正好三个;这可以通过以下代码实现:
Set<Integer> randomIndexesToChange = new HashSet<>();
while (randomIndexesToChange.size() < 3) {
randomIndexesToChange.put( ... another random number from (0, 8) );
}
或者按照 RealSceptic 的建议,您创建一个仅包含从 0 到 8 的所有索引的集合对象;然后你使用随机播放;然后选择前三个:
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
...
用 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,因此您可能想要反驳它。一种方法可能是也为 N 提供计数并相应地增加 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)
将 return 0 之间的整数(包括) 和 bound
(不包括)我们需要传入 numNs + 1
以便如果没有更多 Ns 可用我们使用绑定 1 因为它是排他的我们总是得到 0,它小于numOs
只要有Os个可用(从而得到100%的概率)。
基于@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.
在这个程序中,我想用三个 '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();
}
}
你需要分开循环。
先用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++;
}
}
有时一点点抽象会让事情变得容易得多。
为什么在你的循环中做随机的东西?您的约束是您希望九个数组索引中的三个“不同”。因此:不要迭代数组并在其中调用随机函数。
只需在 (0,8) 范围内创建随机数,直到获得三个不同的值;然后更新数组中的相应索引。
你看,棘手的部分是 正好三个;这可以通过以下代码实现:
Set<Integer> randomIndexesToChange = new HashSet<>();
while (randomIndexesToChange.size() < 3) {
randomIndexesToChange.put( ... another random number from (0, 8) );
}
或者按照 RealSceptic 的建议,您创建一个仅包含从 0 到 8 的所有索引的集合对象;然后你使用随机播放;然后选择前三个:
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
...
用 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,因此您可能想要反驳它。一种方法可能是也为 N 提供计数并相应地增加 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)
将 return 0 之间的整数(包括) 和 bound
(不包括)我们需要传入 numNs + 1
以便如果没有更多 Ns 可用我们使用绑定 1 因为它是排他的我们总是得到 0,它小于numOs
只要有Os个可用(从而得到100%的概率)。
基于@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.