[英]Java Math.random with arrays
我正在嘗試在2d數組中的隨機坐標中用像A這樣的字符填充5 x 5的2d數組。 當我使用嵌套的for循環時,我想繪制2d數組的坐標,其中我的char將是隨機的。 因此,可以說我要求A的40%,在5乘5的情況下,我應該得到10個A,但是我得到8。當我運行它時,它沒有顯示我有時想要的A的百分比。 它只會打印出6。這是因為,如果if語句中的row和col是隨機的,那么for循環中的row和col是嗎? 這就是為什么如果數字隨機化2d數組的長度為5時,由於for循環停止而使char有時填充的數量少於要求的數量的原因?
同樣,當它確實打印出10個字符時,有時它們會超過5個乘以5。例如,該行中為2 As,第二行為7,第三行為1。 這是為什么?
public static void grid(char[][] arr, int percentofchar)
{
double charx = 0.0;
double totalpercentchar = 0;
totalpercentchar = (double) percentofchar / 100;
cellx = totalpercentchar * (arr.length * arr.length);
for (int row = 0; row < arr.length; row++)
{
for (int col = 0; col < arr[row].length; col++)
{
if (charx > 0)
{
row = (int) (Math.random() * arr.length);
col = (int) (Math.random() * arr.length);
charx--;
arr[row][col] = 'A';
System.out.print(arr[row][col] + " ");
}
}
System.out.println();
}
}
您的代碼應類似於
public static void grid(char[][] array, int percentOfChar)
{
int charsToPlace = (int) (percentOfChar * array.length * array.length / 100.0);
while (charsToPlace > 0)
{
int row = (int) (Math.random() * array.length);
int column = (int) (Math.random() * array.length);
if (array[row][column] != 'A');
{
array[row][column] = 'A';
charsToPlace--;
System.out.print(array[row][column] + " ");
}
}
System.out.println();
}
如果只想在隨機位置插入一個字符,則無需遍歷數組並使用嵌套循環。
也
這是因為如果if語句中的row和col是隨機的,那么for循環中的row和col是隨機的嗎? 這就是為什么如果數字隨機化2d數組的長度為5時,由於for循環停止而使char有時填充的數量少於要求的數量的原因? 同樣,當它確實打印出10個字符時,有時它們會超過5個乘以5。例如,該行中為2 As,第二行為7,第三行為1。 這是為什么?
或多或少。 您可以對行和列進行隨機化,但是這樣做可能會導致遍歷數組的迭代過早結束。 在最壞的情況下,請考慮如果第一次輸入if
語句時,隨機函數將4個值同時分配給row
和col
。 通常,您確定在grid
方法的charx
始終等於0嗎?
注意事項
正如Matt在下面的注釋中指出的那樣,該方法不檢查數組。 因此,假設該數組始終為正方形(即,行X列= n X n)。 如果要強制使用方陣,則可能需要創建包裝器類,例如
class IntegerSquareArray
{
public final int length;
int[][] array;
IntegerSquareArray(int length)
{
this.length = length;
this.array = new int[length][length];
}
public int getValue(int row, int column)
{
if (row < length && column < length)
return array[row][column];
throw new IllegalArgumentException();
}
public void setValue(int row, int column, int value)
{
if (row < length && column < length)
array[row][column] = value;
else throw new IllegalArgumentException();
}
}
然后,您只需將grid
代碼更改為
public static void grid3(IntegerSquareArray integerSquareArray,
int percentOfChar)
{
int charsToPlace = (int) (percentOfChar * integerSquareArray.length
* integerSquareArray.length / 100.0);
while (charsToPlace > 0)
{
int row = (int) (Math.random() * integerSquareArray.length);
int column = (int) (Math.random() * integerSquareArray.length);
if (integerSquareArray.getValue(row, column) != 'A')
{
integerSquareArray.setValue(row, column, 'A');
charsToPlace--;
System.out.print(integerSquareArray.getValue(row, column) + " ");
}
}
System.out.println();
}
為了完整起見 ,這是我在Tigerjack解決方案下的評論中提到的內容 。 根據評論,我將為網格使用包裝器,而不是原始多維數組。
我的隨機布局解決方案稍微復雜一點,但是對於更高的布局百分比(例如,如果您要填充超過90%的單元格),效率將會更高,並且始終會填充完全指定的字符百分比。
如果需要的話,可以在percentOfCellsToSet
較低時使用Tigerjack方法進行隨機放置,而在percentOfCellsToSet
較高時可以使用setRandomCells()
方法中的if
語句使用該方法。
這是我使用洗牌列表方法的完整可編譯示例:
import java.awt.Point;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MyGrid
{
private int width;
private int height;
private char[][] grid;
public MyGrid(int width, int height, char defaultCell)
{
this.width = width;
this.height = height;
grid = new char[height][width];
// populate grid with defaultCells:
for(int x=0; x < width; ++x)
{
for(int y=0; y < height; ++y)
{
grid[y][x] = defaultCell;
}
}
}
public int getWidth() { return width; }
public int getHeight() { return height; }
public char getCell(int x, int y) { return grid[y][x]; }
public void setCell(int x, int y, char cellValue) { grid[y][x] = cellValue; }
public void setRandomCells(char cellValue, float percentOfCellsToSet)
{
// determine the number of cells to set (rounding to nearest int):
int numCellsToSet = (int)(Math.round((width * height * percentOfCellsToSet) / 100.0));
// create a list containing all possible cell positions:
List<Point> listAllCellLocations = new ArrayList<>();
for(int x=0; x < width; ++x)
{
for(int y=0; y < height; ++y)
{
listAllCellLocations.add(new Point(x,y));
}
}
// shuffle it
Collections.shuffle(listAllCellLocations);
// now set the cells
for(int i=0; i < numCellsToSet; ++i)
{
Point pt = listAllCellLocations.get(i);
setCell(pt.x, pt.y, cellValue);
}
}
public void debugPrintGrid()
{
for(int y=0; y < height; ++y)
{
for(int x=0; x < width; ++x)
{
System.out.print(getCell(x,y));
}
System.out.println();
}
}
public static void main(String[] args)
{
MyGrid myGrid = new MyGrid(10, 10, '0');
myGrid.setRandomCells('A', 68);
myGrid.debugPrintGrid();
}
}
這是main()
方法中代碼的示例輸出:
AAAA0A0AAA
0AAAAAAAA0
A00A00AA0A
AAAAA0AAA0
AA0A0AAAA0
0A0AAAA0AA
A0AAA0A0AA
A0A00AAAAA
AAA000A0A0
0AA0AAA0A0
希望有人覺得這有幫助。
您為循環變量分配了隨機值...現在,它具有不確定性...
基本上,如果第一個Math.random()
結果為arr.length - 1
,第二個結果為arr[arr.length - 1].length -1
則嵌套循環將結束。
我嚴重懷疑這是您想要的。
要控制要放入數組中的隨機A
,只需為此使用循環,但不要將隨機值分配給循環變量:
int max = arr.length * arr.length * percentofchar / 100;
for (int i = 0; i < max; i++) {
// Put `A` at a random location
int row = (int) (Math.random() * arr.length);
int col = (int) (Math.random() * arr.length);
arr[row][col] = 'A';
System.out.print(arr[row][col] + " ");
}
還要注意,這可能仍會導致A
小於百分比的含義,因為相同的隨機位置可能會多次生成,因此同一數組元素可能會多次設置為A
如果要生成A
的確切計數,則必須重試隨機位置是否已經是A
:
int max = arr.length * arr.length * percentofchar / 100;
for (int i = 0; i < max; i++) {
// Put `A` at a random location
int row, col;
do {
row = (int) (Math.random() * arr.length);
col = (int) (Math.random() * arr.length);
} while (arr[row][col] == 'A');
arr[row][col] = 'A';
System.out.print(arr[row][col] + " ");
}
您的代碼隨機放置“ A”,因此某些“ A”可能放置在同一位置。
讓我們計算可能性,看得出10個“ A”作為結果。
第一個“ A”始終是空位,因此您會看到100%處有1個“ A”。放置第二個“ A”時,“ A”占據了1個位置,空位為24個,因此在放置第二個后便看到了2個“ A” “ A”為96%。 (第二個A可能放置在25(4%)中第一個“ A”在可能性1中放置的位置。第三,可能性是(24/25)*(23/25)。...在第4至第9個中省略。對於第10個,則可能會出現(24/25) (23/25) (22/25) (21/25) (20/25) (19/25) (18/25) (17/25 )的 10個“ A” ) (16/25)。(該值約為12.4%)
此計算表明,您的代碼可能會每8個結果顯示10個“ A”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.