因此,我是一个初学者,并且正在构建C#Crozzle游戏。我试图在二维数组中寻找可以存储单词的空间。因此,例如,我有一个二维数组,如下所示:
[ 0 1 1 0 0 0 0 ]
[ 0 1 1 0 1 1 1 ]
[ 0 1 1 0 1 1 1 ]
[ 0 1 1 0 1 1 1 ]
[ 0 1 1 0 1 1 1 ]
0表示单元格为空,1表示它包含一个值。我想获取免费的坐标集合。
所以最终我想存储起点和终点坐标,例如:
[0,0]-> [0,4],
[3,0]-> [3,4],
[3,0]-> [6,0]
存储它们不是问题,问题在于找到这些0的模式。任何人都知道解决此问题的最佳方法吗?
谢谢!
最佳答案
您必须扫描2D阵列的行和列。为了展示这个想法,我选择了
Tuple<int, int>
Tuple<Point, Point>
分别代表一维和二维数组中的范围。当然,
Tuple<Point, Point>
并不是一个很好的选择,您可能想为某些定制的类更改它。private static IEnumerable<Tuple<int, int>> ScanLine<T>(IEnumerable<T> source, T sample, int atLeast) {
int count = 0;
int index = -1;
foreach (var item in source) {
index += 1;
if (Object.Equals(item, sample))
count += 1;
else {
if (count >= atLeast)
yield return new Tuple<int, int>(index - count, index - 1);
count = 0;
}
}
if (count >= atLeast)
yield return new Tuple<int, int>(index - count + 1, index);
}
private static IEnumerable<Tuple<Point, Point>> ScanBoard<T>(T[,] source, T sample, int atLeast) {
// Lines scan
for (int i = 0; i < source.GetLength(0); ++i) {
var line = Enumerable.Range(0, source.GetLength(1)).Select(c => source[i, c]);
foreach (var item in ScanLine(line, sample, atLeast))
yield return new Tuple<Point, Point>(new Point(item.Item1, i), new Point(item.Item2, i));
}
// Columns scan
for (int i = 0; i < source.GetLength(1); ++i) {
var line = Enumerable.Range(0, source.GetLength(0)).Select(r => source[r, i]);
foreach (var item in ScanLine(line, sample, atLeast))
yield return new Tuple<Point, Point>(new Point(i, item.Item1), new Point(i, item.Item2));
}
}
测试
int[,] board = new int[,] {
{ 0, 1, 1, 0, 0, 0, 0 },
{ 0, 1, 1, 0, 1, 1, 1 },
{ 0, 1, 1, 0, 1, 1, 1 },
{ 0, 1, 1, 0, 1, 1, 1 },
{ 0, 1, 1, 0, 1, 1, 1 },
};
// room for 3-letter words
Console.Write(String.Join(Environment.NewLine, ScanBoard(board, 0, 3)));
退货
({X=3,Y=0}, {X=6,Y=0})
({X=0,Y=0}, {X=0,Y=4})
({X=3,Y=0}, {X=3,Y=4})