带有数组的Java Math.random

时间:2014-11-11 05:43:02

标签: java arrays random

我正在尝试在2d数组中随机坐标中使用诸如A之类的字符填充5 x 5的数组。当我使用嵌套for循环时,我想制作2d数组的坐标,其中我的char将是随机的。所以我要问我40%的A,在5乘5我应该得到10 A但我得到8.当我运行时,它没有显示我想要的A的百分比。它只会像6那样打印出来。这是因为当if语句中的row和col随机化时,for循环中的row和col也是如此吗?这就是为什么char有时会填充少,然后要求,因为如果数字随机化2d数组的长度为5,for循环停止?

此外,当它打印出10个字符时,有时它们会超过5乘以5.例如,在行中为7,在第二个中为7,在第3个中为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();
  }
}

4 个答案:

答案 0 :(得分:2)

你的代码应该是

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循环中的行和col也是如此?这就是char有时会填充的原因   然后请求,因为for循环停止,如果数字   随机化2d数组的长度是5?当它确实打印出10个字符时,   有时他们会超过5乘5。一个例子就是2   第二行是7行,第3行是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();
}

答案 1 :(得分:1)

为了完整起见,我在tigerjack's解决方案的评论中提到了这一点。根据评论,我会使用网格的包装器而不是原始的多维数组。

我的随机放置解决方案有点复杂,但对于更高的放置百分比(即,如果您尝试填充超过90%的单元格)将更有效,并且将始终填充精确指定的字符百分比。

如果需要,您可以在percentOfCellsToSet较低时使用tigerjack方法进行随机展示位置,percentOfCellsToSet使用if语句中的setRandomCells()语句时使用此方法。

这是我使用混洗列表方法的完整可编译示例:

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

希望有人觉得这很有帮助。

答案 2 :(得分:0)

您可以将随机值分配给循环变量......现在这可能是不确定的......

基本上,如果第一个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] + "  ");
}

答案 3 :(得分:0)

你的代码随机地放置了#34; A&#34; A&#34; A&#34; A&#34;可以放在同一个地方。

让我们计算看看10&#34; A&#34; s的可能性。

首先&#34; A&#34;永远是空的地方,所以你看到1&#34; A&#34;在100% 对于第二个&#34; A&#34;,有一个地方被&#34; A&#34;和24个空位,所以你看到2&#34; A&#34;放置第二个&#34; A&#34;在96%。 (第二个A可以放在第一个&#34; A&#34;放置在25个可能性中的1个(4%)。 第三,可能性是(24/25)*(23/25)。   ...在第4到第9节省略。 对于10日,你看到10&#34; A&#34; s的可能性为(24/25)(23/25)(22/25)(21/25)(20/25)(19/25)(18/25)(17/25)(16/25)。 (价值约为12.4%)

此计算表明,您的代码可能会在结果中显示10&#34; A&#34;大约一到八次。