簡體   English   中英

Java Math.random與數組

[英]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個值同時分配給rowcol 通常,您確定在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM