【发布时间】:2014-11-03 05:24:09
【问题描述】:
我正在尝试找到相邻空单元格的最大连接区域(对角连接计数)。
例如,如果我有一个这样的矩阵(“”-Empty,“F”-Filled)
{" "," "," ","F"},
{"F","F","F"," "},
{" "," ","F"," "}
结果应该是:
{"*","*","*","F"},
{"F","F","F","*"},
{" "," ","F","*"}
除了旧的 BFS/DFS 之外还有其他想法吗?
这是我的工作代码(通过 BFS 解决):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _09.LargestConnectedArea
{
class Program
{
public static string[,] matrix;
public static int mRow, mCol;
public static void Input(string mode = "mid")
{
if (mode.Equals("top"))
{
matrix = new string[4, 4]{
{" "," "," "," "},
{" "," "," "," "},
{"F"," "," ","F"},
{" ","F","F"," "}
};
mRow = matrix.GetLength(1);
mCol = matrix.GetLength(0);
}
else if (mode.Equals("mid"))
{
matrix = new string[4, 4]{
{"F","F","F"," "},
{" "," "," "," "},
{"F"," "," ","F"},
{"F","F","F","F"}
};
mRow = matrix.GetLength(1);
mCol = matrix.GetLength(0);
}
else if (mode == "test")
{
// matrix = new string[4, 4];
matrix = new string[7, 4]{
{" ","F","F"," "},
{"F","F"," "," "},
{" "," "," ","F"},
{"F","F"," "," "},
{" ","F"," ","F"},
{" ","F"," ","F"},
{" ","F"," ","F"}
};
mRow = 7;
mCol = 4;
}
else
{
Console.Write("maxrow: ");
mRow = int.Parse(Console.ReadLine());
Console.Write("maxcol: ");
mCol = int.Parse(Console.ReadLine());
matrix = new string[mRow, mCol];
for (int row = 0; row < mRow; row++)
{
Console.WriteLine();
Console.WriteLine("Row {0}:", row);
Console.WriteLine();
for (int col = 0; col < mCol; col++)
{
Console.Write("Element {0}:", col);
matrix[row, col] = Console.ReadLine();
}
}
}
}
public static int BFS(Stack<Tuple<int, int>> currPath, string symbol = "*", int counter = 0)
{
if (currPath.Count == 0)
{
return counter;
}
else
{
;
Tuple<int, int> top = new Tuple<int, int>(currPath.Peek().Item1, currPath.Pop().Item2);
matrix[top.Item1, top.Item2] = symbol;
counter++;
//top TEST: PASSED
#region
if (top.Item1 > 0)
{
//_X_
if (matrix[top.Item1 - 1, top.Item2].Equals(" "))
{
matrix[top.Item1 - 1, top.Item2] = symbol;
currPath.Push(new Tuple<int, int>(top.Item1 - 1, top.Item2));
}
//X__
if (top.Item2 > 0)
{
if (matrix[top.Item1 - 1, top.Item2 - 1].Equals(" "))
{
matrix[top.Item1 - 1, top.Item2 - 1] = symbol;
currPath.Push(new Tuple<int, int>(top.Item1 - 1, top.Item2 - 1));
}
}
//__X
if (top.Item2 < mCol - 1)
{
if (matrix[top.Item1 - 1, top.Item2 + 1].Equals(" "))
{
matrix[top.Item1 - 1, top.Item2 + 1] = symbol;
currPath.Push(new Tuple<int, int>(top.Item1 - 1, top.Item2 + 1));
}
}
}
#endregion
//mid TEST: PASSED
#region
if (top.Item2 > 0)
{
if (matrix[top.Item1, top.Item2 - 1].Equals(" "))
{
matrix[top.Item1, top.Item2 - 1] = symbol;
currPath.Push(new Tuple<int, int>(top.Item1, top.Item2 - 1));
}
}
if (top.Item2 < mCol - 1)
{
if (matrix[top.Item1, top.Item2 + 1].Equals(" "))
{
matrix[top.Item1, top.Item2 + 1] = symbol;
currPath.Push(new Tuple<int, int>(top.Item1, top.Item2 + 1));
}
}
#endregion
//bot TEST: PASSED
#region
if (top.Item1 < mRow - 1)
{
//_X_
if (matrix[top.Item1 + 1, top.Item2].Equals(" "))
{
matrix[top.Item1 + 1, top.Item2] = symbol;
currPath.Push(new Tuple<int, int>(top.Item1 + 1, top.Item2));
}
//X__
if (top.Item2 > 0)
{
if (matrix[top.Item1 + 1, top.Item2 - 1].Equals(" "))
{
matrix[top.Item1 + 1, top.Item2 - 1] = symbol;
currPath.Push(new Tuple<int, int>(top.Item1 + 1, top.Item2 - 1));
}
}
//__X
if (top.Item2 < mCol - 1)
{
if (matrix[top.Item1 + 1, top.Item2 + 1].Equals(" "))
{
matrix[top.Item1 + 1, top.Item2 + 1] = symbol;
currPath.Push(new Tuple<int, int>(top.Item1 + 1, top.Item2 + 1));
}
}
}
#endregion
return BFS(currPath, symbol, counter);
}
}
public static void Print(string[,] a)
{
for (int row = 0; row < mRow; row++)
{
for (int col = 0; col < mCol; col++)
{
Console.Write("\'{0}\' ", a[row, col]);
}
Console.WriteLine();
}
Console.WriteLine();
}
static void Main(string[] args)
{
Input("test");
Print(matrix);
List<Tuple<char, int>> areaCalculated = new List<Tuple<char, int>>();
char symbol = '1';
//Console.WriteLine(BFS(a, symbol + ""));
for (int row = 0; row < mRow; row++)
{
for (int col = 0; col < mCol; col++)
{
if (matrix[row, col].Equals(" ") == true)
{
Stack<Tuple<int, int>> a = new Stack<Tuple<int, int>>();
a.Push(new Tuple<int, int>(row, col));
areaCalculated.Add(new Tuple<char, int>(symbol, BFS(a, symbol + "")));
symbol++;
}
}
}
areaCalculated.Sort((x, y) => y.Item2.CompareTo(x.Item2));
Print(matrix);
Console.WriteLine("The largest connected area of adjacent empty cells(diagonal connection counts) is marked with the \'"+areaCalculated.ElementAt(0).Item1 + "\' symbol and contains " + areaCalculated.ElementAt(0).Item2 + " cells.");
// Console.WriteLine(areaCalculated.ElementAt(areaCalculated.Count - 1).Item1 + " " + areaCalculated.ElementAt(areaCalculated.Count - 1).Item2);
}
}
}
【问题讨论】:
-
定义相邻。您是指仅在同一行中的相邻单元格,还是包含列?您的结果表明相邻包括对角线,因为最后两行的最后一列带有
* -
然后发布您的代码,或者至少几行关于您的尝试如何解决它的描述。如果您的解决方案有效,那么这似乎更适合 codereview.stackexchange.com
-
相邻的意思是单元格至少有一个共同的边缘/边。很抱歉在这里发布这个(我是stackoverflow的新手)。也许你是对的,也许是为了代码审查。我在这里发布它的原因只是为了收集一些新的想法,也许是为了找到比我更好的解决方案。附言我将编辑问题并发布代码。 :)
-
这个问题似乎是题外话,因为它属于codereview.stackexchange.com
-
为了标记整个连接区域,我建议查看 Flood Fill 算法及其分析,以优化(按常数,而不是数量级)运行时间 - en.wikipedia.org/wiki/Flood_fill。除此之外,它会根据您获得的实际输入类型变得非常具体