如果二维数组中的位置都是"触及"我想找到一种能够返回的方法。和类似的值,一路追踪。在我进入这个问题之前,有一个非常相似的问题,并解决here,但它是用python编写的,我对此一无所知。进一步扩展:
f f f f
f T T f
f T T f
f f f f
从[0][0]
开始,它将返回该数组中的所有谬误,因为它们是相同的值并链回[0][0]
。
f f f T f f f
f T f T f T f
f f f T f f f
但基于此问题,从[0][0]
开始只会返回[0][0,1,2]
,[1][0,2]
和[2][0,1,2]
。但是如果你从[0][4]
开始,那么它将返回[n][3]
之后的所有谬误,因为它们与开始时的值相同,并且触及。
不是在寻找任何人来帮助我准确地编写代码,但可能会指出我正确的方向。请提前原谅我的新手级别,非常感谢你!
答案 0 :(得分:1)
您似乎遇到了图形问题,而您正在寻找广度优先搜索或类似算法
f
)数组项实现:
private static IEnumerable<Tuple<int, int>> Touching(char[,] items,
Tuple<int, int> startAt,
char letter = 'f') {
if (startAt.Item1 < 0 || startAt.Item1 >= items.GetLength(0) ||
startAt.Item2 < 0 || startAt.Item2 >= items.GetLength(1))
yield break; // or throw ArgumentOutOfRangeException
else if (items[startAt.Item1, startAt.Item2] != letter)
yield break;
Queue<Tuple<int, int>> agenda = new Queue<Tuple<int, int>>();
HashSet<Tuple<int, int>> visited = new HashSet<Tuple<int, int>>() { startAt };
agenda.Enqueue(startAt);
while (agenda.Any()) {
for (int i = agenda.Count - 1; i >= 0; --i) {
var point = agenda.Dequeue();
yield return point;
// Manhattan: left, right, top, bottom neighbors only, no diagonal ones
var validNeighbors = new Tuple<int, int>[] {
new Tuple<int, int>(point.Item1 - 1, point.Item2), // left
new Tuple<int, int>(point.Item1 + 1, point.Item2), // right
new Tuple<int, int>(point.Item1, point.Item2 - 1), // top
new Tuple<int, int>(point.Item1, point.Item2 + 1),} // bottom
.Where(p => p.Item1 >= 0 && p.Item1 < items.GetLength(0)) // Within array
.Where(p => p.Item2 >= 0 && p.Item2 < items.GetLength(1)) // Within array
.Where(p => items[p.Item1, p.Item2] == letter) // valid point
.Where(p => visited.Add(p)); // not visited
foreach (var p in validNeighbors)
agenda.Enqueue(p);
}
}
}
测试:
char[,] data = new char[,] {
{ 'f', 'f', 'f', 'T', 'f', 'f', 'f',},
{ 'f', 'f', 'f', 'T', 'f', 'f', 'f',},
{ 'f', 'f', 'f', 'T', 'f', 'f', 'f',},
};
string report = string.Join(Environment.NewLine,
Touching(data, new Tuple<int, int>(0, 0), 'f'));
Console.WriteLine(report);
结果(以下所有这些项目都在触及startAt
点<{1}}点 - (0, 0)
):
(0, 0)
(1, 0)
(0, 1)
(2, 0)
(1, 1)
(0, 2)
(2, 1)
(1, 2)
(2, 2)
在 Linq 的帮助下,您可以以不同的方式组织报告(如问题中所示):
var report = string.Join(Environment.NewLine,
Touching(data, new Tuple<int, int>(0, 0), 'f')
.GroupBy(item => item.Item1, item => item.Item2)
.OrderBy(chunk => chunk.Key)
.Select(chunk => $"[{chunk.Key}][{string.Join(", ", chunk.OrderBy(x => x))}]"));
并在下面做出回应:
[0][0, 1, 2]
[1][0, 1, 2]
[2][0, 1, 2]