我正在尝试从填充0而不是1的2个数组列表中随机获取特定的整数(1)。我做了这个,它的确有效:
while (wallsList[randomX, randomY] != 1)
{
randomX = randomizer.Next(34);
randomY = randomizer.Next(34);
}
它的缺点是,它需要花费太多时间才能找到一次int(1),并且我必须执行这个过程超过1000次,因为每次添加新的1并将其移除到2D阵列。启动我的程序需要大约3米,所以我想知道是否有这个的优化版本,我搜索了很多,只找到了这个1D阵列的解决方案。谢谢你的时间。
答案 0 :(得分:3)
你有一个稀疏数组。为什么不将它表示为X / Y int对的列表?然后,如果X / Y int对在列表中,则为1,如果不是,则为0。
然后,要查找包含1的随机值/单元格,只需从列表中选择一个随机值。
您可以使用
之类的列表new List <Tuple<int, int>> { new Tuple<int, int>(1, 5), new Tuple<int, int>(2, 7) }
答案 1 :(得分:3)
由于您的大多数随机猜测都会失败,因此建立第二组已知良好索引并随机搜索那些索引会更加高效
。var randomizer = new Random();
var wallsList = new int[34, 34];
wallsList[23,11] = 1;
// Build an array of points that are known to pass
var knownHits =
(from x in Enumerable.Range(0, 34)
from y in Enumerable.Range(0, 34)
where wallsList[x, y] == 1
select new { x, y })
.ToArray();
// Pick a random point from previous array
var randomPoint = knownHits[randomizer.Next(knownHits.Length)];
var randomX = randomPoint.x;
var randomY = randomPoint.y;
Console.Write($"X = {randomX}, Y = {randomY}"); // X = 23, Y = 11
或者,您可以像这样构建辅助数组:
var knownHits = wallsList.Cast<int>()
.Select((v, i) => new { v, x = i / 34, y = i % 34 })
.Where(x => x.v == 1)
.ToArray();
答案 2 :(得分:0)
您可以采取一些方法。一种方法是将您的表示从二维数组更改为类似坐标对的列表。现在随机选择一个很容易,但也许你想要执行的其他操作变得更难。这种方法和你的方法的优点是它可以选择1&#39> 统一中的一个。另一种牺牲这种质量的方法是选择随机的x和y,然后返回下一个1,扫描x或y。这也没有第一个解决方案那么有效。
答案 3 :(得分:0)
我正在尝试随机从填充了0的二维数组列表中获取一个特定的整数(1)而不是很多
如果你必须随机做,你的方法很好。但是,您可以通过避免再次绘制相同的索引来改进它:
var randomizer = new Random();
var wallsList = new int[34, 34];
wallsList[01, 23] = 1;
var indexes =
from x in Enumerable.Range(0, 34)
from y in Enumerable.Range(0, 34)
select new { X = x, Y = y };
var result = indexes
.OrderBy(_ => randomizer.Next())
.FirstOrDefault(index => wallsList[index.X, index.Y] == 1);
if (result == null)
throw new Exception("Index not found");
Console.WriteLine("1 is found at[{0}, {1}]", result.X, result.Y);