C#查找相邻空单元格的最大连通区域(字符串[,])

时间:2014-09-09 17:25:20

标签: c# string matrix area

我试图找到相邻空单元的最大连接区域(对角线连接计数)。

例如,如果我有这样的矩阵("" -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);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

感谢您的练习,这是我的尝试

var wspace = new List<Tuple<int, int>>();
string[,] cells = { 
    { "F", " ", "F", "F", "F", "F", " " }, 
    { "F", "F", "F", " ", "F", "F", " " }, 
    { "F", " ", "F", " ", "F", " ", "F" },
    { "F", "F", " ", "F", "F", " ", "F" },
    { "F", " ", "F", " ", "F", " ", "F" }
};

for (int i = 0; i < cells.GetLength(0); i++)
    for (int j = 0; j < cells.GetLength(1); j++)
        if (cells[i, j] == " ")
            wspace.Add(new Tuple<int, int>(i, j));

var region = new List<Tuple<int, int>>();
var pre = new List<Tuple<int, int>>();
var regions = new List<List<Tuple<int, int>>>();
region.Add(wspace.First());
wspace = wspace.Skip(1).ToList();

for(int z=0; z<wspace.Count(); z++)
{
    var pos = wspace[z];
    bool keep = true;
    for (int i = -1; i < 2 && keep; i++)
    {
        for (int j = -1; j < 2 && keep; j++)
        {
            if (region.Any(x => x.Item1 == (pos.Item1 + i) && x.Item2 == (pos.Item2 + j)))
            {
                pre.Reverse();
                wspace.AddRange(pre);
                pre.Clear();
                region.Add(pos);
                keep = false;
            }
        }
    }

    if (keep && (pos.Item1 > region.Last().Item1) && (pos.Item2 > region.Last().Item2))
    {
        regions.Add(region.ToList());
        region.Clear();
        region.Add(pos);
    }
    else if (keep) pre.Add(pos);

}
regions.Add(region);
region = regions.OrderBy(x => x.Count).Last().OrderBy(s => s.Item1 * cells.GetLength(1) + s.Item2).ToList();

region.ForEach(x => Console.WriteLine("Array: {0} Key: {1}", x.Item1 + 1, x.Item2 + 1));

到目前为止它运作良好,试着告诉我

实际输出

Array: 2 Key: 4
Array: 3 Key: 2
Array: 3 Key: 4
Array: 4 Key: 3
Array: 5 Key: 2
Array: 5 Key: 4