我面临着将char置于随机位置的问题。
我有一个装满点的桌子,我必须用*
替换这些点的30%
尺寸:10x5
我使用了函数Random
。
Random rnd = new Random();
if (rnd.Next() % 10 > 3)
Console.Write(". ");
else
Console.Write("* ");
所有东西都在2个循环中,它包含表格的长度和高度(10x5)。
但它仅使30%的概率成为*
而不是.
这需要很好的位置,但每次我开始一个程序时都有不同的*
。
每次启动程序时,它应该只有16 *
(17 - 如果舍入)
我应该如何设定30%而不是概率?
答案 0 :(得分:5)
你有50个点。计算50*30/100
,它变为15。
然后在0到50范围内生成15个唯一的随机数。这些数字是您必须用.
替换*
的索引
var indexes = Enumerable.Range(0,50).OrderBy(x => rng.Next()).Take(50*30/100).ToList();
如果您正在使用2d索引,则很容易将1d索引转换为2d索引。
var i = index % 5;
var j = index / 5;
根据@KonradRudolph的说法,如果你不想使用OrderBy,你可以查看其他方法来重新排列数组(或创建随机集)Best way to randomize an array with .NET
Here is more efficient way using Fisher-Yates algorithm我建议您使用而不是使用OrderBy
var indexes = Enumerable.Range(0, 50).ToArray();
RandomExtensions.Shuffle(rng, indexes);
答案 1 :(得分:2)
编写执行以下操作的代码:
答案 2 :(得分:0)
想象一下你的阵列只有50个元素,暂时忘掉矩形。你会怎么做?声明X点和50-X星,然后随机排序。就像你随机订购1> 50的数字列表一样。
现在如何随机订购1> 50个数字的列表?一种简单直观的方式是想象洗牌。遍历循环并且对于每个位置获得1-> 50的随机数。选择交换元素(例如,对于i = 1,我们得到随机数7 =>交换元素1和7)。
在这里,你只需要将这个矩形映射到那些50个点,这对于2D来说是微不足道的。
答案 3 :(得分:0)
我会随机选择30%的可能位置
// create char array
int arrayRows = 5;
int arrayCols = 10;
char[,] arr= new char[arrayRows ,arrayCols];
// populate array with dots
for (int i = 0; i < arrayRows; i++)
{
for (int j = 0; j < arrayCols; j++)
{
arr[i,j] = '.';
}
}
Random rnd = new Random();
int numberOfPossiblePositions = arrayRows * arrayCols;
int k = 0;
while (k < numberOfPossiblePositions * 0.3) {
int position = rnd.Next(numberOfPossiblePositions);
int colIndex = position / 10;
int rowIndex = position % 10;
// if the cell already has * try again
if (arr[rowIndex,colIndex] == '*') {
continue;
}
arr[rowIndex,colIndex] = '*';
k++;
}
答案 4 :(得分:0)
创建一个包含x * y / 3开始的数组,其余的是点。随机排序并迭代它。
这是数组:
Enumerable.Range(0, count).Select(i => new {Text = "*", Order = rnd.Next() })
.Concat(Enumerable.Range(0, x*y - count)
.Select(i=>new { Text = ".", Order = rnd.Next() }))
.OrderBy(i => i.Order).Select(i=>i.Text).ToList();
这是迭代的代码:
Random rnd = new Random();
int x = 10;
int y = 5;
int count = x*y/3;
var allPlaces =
Enumerable.Range(0, count).Select(i => new {Text = "*", Order = rnd.Next() })
.Concat(Enumerable.Range(0, x*y - count)
.Select(i=>new { Text = ".", Order = rnd.Next() }))
.OrderBy(i => i.Order).Select(i=>i.Text).ToList();
for (var i = 0; i < x; x++)
{
for (var j = 0; j < y; j++) { Console.Write(allPlaces[i*j + j]); }
Console.WriteLine();
}