2014-09-09 1 views
1

인접한 빈 셀의 최대 연결 영역 (대각선 연결 개수)을 찾으려고합니다. 예를 들어 C# 인접한 빈 셀 (문자열 [,])의 가장 큰 연결 영역 찾기

이 같은 행렬이있는 경우

(""- 빈을, "F"채워진)

{" "," "," ","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); 
     } 
    } 
} 
+0

정의 인접한. 인접한 셀이 같은 행에만있는 것을 의미합니까, 아니면 열을 포함합니까? 결과는 인접한 행이 대각선을 포함하고 있다는 것을 의미합니다. 마지막 행의 마지막 행에'* '가 있기 때문에 –

+0

코드를 게시하거나 시도가 어떻게 달라 졌는지에 대해 최소한 몇 줄의 설명을 게시하십시오. 솔루션이 작동한다면, 이것은 http://codereview.stackexchange.com/에 더 잘 맞는 것처럼 보입니다. –

+0

옆에있는 말은 적어도 하나의 공통 에지/측면이있는 셀을 의미합니다. 그리고 여기에 게시하는 것에 대해 유감스럽게 생각합니다 (저는 stackoverflow를 처음 사용합니다). 어쩌면 당신 말이 맞을 것입니다, 아마도 그것은 codereview를위한 것입니다. 제가 여기에 올린 이유는 신선한 아이디어를 모으고 아마 제 것보다 더 나은 해결책을 찾는 것입니다. P. 나는 질문을 편집하고 코드를 게시 할 것이다. :) – BobsunShirov

답변

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 
+0

오늘은 시험에 지쳐서 내일 알려 드리겠습니다. 또한 제 솔루션을 맨 위에 올리며, 그것을보고 자유롭게 말해서 최적화 할 수 있는지 말해 보겠습니다. something ^^ – BobsunShirov

+0

@BobsunShirov 코드 업데이트 ^^ 알려주기 – Sam

+0

출력물을 이해하려고합니다. 귀하의 예를위한 가장 큰 연결 영역은 세 개의 10 셀 솔루션입니다. 그것들 중 하나는 시리즈입니다 :''[2,0] [2,1] [3,1] [3,2] [2,3] [3,4] [3,5] [2,5] [1 , 6] [0,6]' –