あなたがグラフ問題を抱えているようだと、あなたは幅優先探索または同様のアルゴリズムを探しているところ
- グラフノード:すべての有効な(
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
ポイントからすなわち到達可能触れている - (0, 0)
):
(0, 0)
(1, 0)
(0, 1)
(2, 0)
(1, 1)
(0, 2)
(2, 1)
(1, 2)
(2, 2)
のLINQの助けを借りて質問のようにさまざまな方法でレポートを整理できます:それはあなたが持っている問題の種類は明らかではありません
[0][0, 1, 2]
[1][0, 1, 2]
[2][0, 1, 2]
:
とは、以下の応答があります。エラー?間違った値が返されますか?また、記述に誤りがあります - '[0] [0,1,2]'が二度言及されました –お詫び申し上げます。私は書き込みを簡略化しようとしていました。それは[0] [0]、[0] [1]、[0] [2]に変換されます。私は、この方向またはその方向のポイントを処理するアルゴリズムのタイプを探していました。ドミトリーは「幅広い最初の検索」の下で私を助けました。ありがとう! –
これは[Flood fill](https://en.wikipedia.org/wiki/Flood_fill)アルゴリズムと呼ばれます。 –