从2D数组中随机选择一个特定的int

时间:2016-06-01 20:22:30

标签: c# arrays

我正在尝试从填充0而不是1的2个数组列表中随机获取特定的整数(1)。我做了这个,它的确有效:

while (wallsList[randomX, randomY] != 1)
{
    randomX = randomizer.Next(34);
    randomY = randomizer.Next(34);
}

它的缺点是,它需要花费太多时间才能找到一次int(1),并且我必须执行这个过程超过1000次,因为每次添加新的1并将其移除到2D阵列。启动我的程序需要大约3米,所以我想知道是否有这个的优化版本,我搜索了很多,只找到了这个1D阵列的解决方案。谢谢你的时间。

4 个答案:

答案 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);