주녘공부일지

[프로그래머스 C#] Lv.3 표 병합 본문

CodingTest/Programmers Lv.3

[프로그래머스 C#] Lv.3 표 병합

주녘 2024. 2. 29. 16:36

https://school.programmers.co.kr/learn/courses/30/lessons/150366

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

1. 정답코드 및 핵심 아이디어, 유의사항

표 편집 프로그램에 명령된 순서에 따라 명령을 수행했을 때, 출력되는 메시지를 구하는 문제

- 각 셀에 대한 좌표는 최대 50 * 50으로, 용이한 접근을 위해 1차원 배열로 변경 // [2501]

 -> 셀 병합을 관리할 int형 배열과 셀 안의 실제 값을 가질 string형 배열을 선언

 

셀 병합을 관리하는 int형 1차원 배열 (intArray)

- 50 * 50의 2500개의 셀을 1차원 배열로 나열해 관리

 -> [r, c]라고 했을 때 49r + c이 1차원 배열의 인덱스가 됨

 -> 병합당하는 셀은 병합하는 셀을 가리킴

즉, 같은 묶음으로 병합된 셀은 최종적으로 병합하는 셀을 가리키게 됨 ( 같은 값을 가짐 )

 

셀의 실제 값을 가지고 있는 string형 1차원 배열 (stringArray)

- 해당 배열에 접근할 때에는 반드시 위의 intArray를 통해서 접근해야 함

 -> 병합된 셀일 수 있으므로 intArray의 가리키는 인덱스의 값이 실제 병합된 셀이 됨

 

각 기능에 대한 유의사항

- 셀 업데이트 : 셀의 값을 바꾸는 경우 병합된 모든 셀을 바꿔줘야 함

- 셀 병합 : 병합하는 셀과 병합당하는 셀을 잘 구분해야 함

- 셀 병합 해제 : 병합 해제를 하려는 셀은 병합된 셀일 수 있음

 -> 같은 인덱스를 가리키는 모든 셀의 실제 값을 비워야 함

 -> 셀에 값이 있었다면 명령받은 셀에 넣어야 함

 

주석 참조

    using System;
    using System.Collections.Generic;

    public class Solution
    {
        string[] stringArray = new string[2501]; // 셀 안의 값
        int[] intArray = new int[2501]; // 인덱스배열 (병합 관리)

        // 셀이 가리키는 인덱스를 반환하는 메서드
        private int GetIndex(string r, string c)
        {
            int num = int.Parse(r) * 49 + int.Parse(c);
            return intArray[num];
        }

        // 셀 안의 값을 반환하는 메서드
        private string GetValue(int index)
        {
            return stringArray[intArray[index]];
        }

        public string[] solution(string[] commands)
        {
            var answerList = new List<string>();

            // 초기화
            for (int i = 1; i < intArray.Length; i++)
            {
                intArray[i] = i;
                stringArray[i] = "";
            }
            
            // 명령 순차 실행
            for (int i = 0; i < commands.GetLength(0); i++)
            {
                string[] strs = commands[i].Split(' ');

                switch (strs[0])
                {
                    case "UPDATE":
                        CellUpdate(strs);
                        break;
                    case "MERGE":
                        CellMerge(strs);
                        break;
                    case "UNMERGE":
                        CellUnmerge(strs);
                        break;
                    case "PRINT":
                        CellPrint(strs, answerList);
                        break;
                }
            }

            return answerList.ToArray();
        }

        // 셀 업데이트
        private void CellUpdate(string[] strs)
        {
            if (strs.Length == 3)
            {
                for (int i = 1; i < stringArray.Length; i++)
                    if (stringArray[i] == strs[1])
                        stringArray[i] = strs[2];
            }
            else // strs.Length == 4
            {
                // 병합된 셀 모두 업데이트
                int index = GetIndex(strs[1], strs[2]);

                for (int i = 1; i < intArray.Length; i++)
                    if (intArray[i] == index)
                        stringArray[i] = strs[3];
            }
        }

        // 셀 병합
        private void CellMerge(string[] strs)
        {
            int index1 = GetIndex(strs[1], strs[2]);
            int index2 = GetIndex(strs[3], strs[4]);

            if (stringArray[index1] == "" && stringArray[index2] != "")
            {
                // index2로 병합
                for (int i = 1; i < intArray.Length; i++)
                    if (intArray[i] == index1)
                        intArray[i] = index2;
            }
            else
            {
                // index1로 병합
                for (int i = 1; i < intArray.Length; i++)
                    if (intArray[i] == index2)
                        intArray[i] = index1;
            }

        }

        // 셀 병합 해제
        private void CellUnmerge(string[] strs)
        {
            int index = GetIndex(strs[1], strs[2]);
            string str = GetValue(index);

            for (int i = 1; i < intArray.Length; i++)
            {
                if (intArray[i] == index)
                {
                    intArray[i] = i;
                    stringArray[i] = "";
                }
            }

            // 해제를 명령한 셀에게 병합된 셀의 값을 넣음
            stringArray[GetIndex(strs[1], strs[2])] = str;
        }

        // 셀의 값을 answerList에 출력
        private void CellPrint(string[] strs, List<string> answerList)
        {
            int index = GetIndex(strs[1], strs[2]);
            string str = GetValue(index);

            if (str == "")
                str = "EMPTY";

            answerList.Add(str);
        }
    }