본문 바로가기
프로그래머스 코딩테스트 문제/Level 1

[프로그래머스] - 문자열 나누기(C#)

by jyppro 2023. 9. 15.

문자열 나누기

오늘은 "문자열 나누기" 문제를 풀어보도록 하겠습니다. 해당 문제의 정답률은 54% 입니다.

문제 설명

문자열 s가 입력되었을 때 다음 규칙을 따라서 이 문자열을 여러 문자열로 분해하려고 합니다.

먼저 첫 글자를 읽습니다. 이 글자를 x라고 합시다.
이제 이 문자열을 왼쪽에서 오른쪽으로 읽어나가면서, x와 x가 아닌 다른 글자들이 나온 횟수를 각각 셉니다. 처음으로 두 횟수가 같아지는 순간 멈추고, 지금까지 읽은 문자열을 분리합니다.
s에서 분리한 문자열을 빼고 남은 부분에 대해서 이 과정을 반복합니다. 남은 부분이 없다면 종료합니다.
만약 두 횟수가 다른 상태에서 더 이상 읽을 글자가 없다면, 역시 지금까지 읽은 문자열을 분리하고, 종료합니다.
문자열 s가 매개변수로 주어질 때, 위 과정과 같이 문자열들로 분해하고, 분해한 문자열의 개수를 return 하는 함수 solution을 완성하세요.

 

제한사항

  • 1 ≤ s의 길이 ≤ 10,000
  • s는 영어 소문자로만 이루어져 있습니다.

 

입출력 예

s result
"banana" 3
"abracadabra" 6
"aaabbaccccabba" 3

 

입출력 예 설명

입출력 예 #1
s="banana"인 경우 ba - na - na와 같이 분해됩니다.

입출력 예 #2
s="abracadabra"인 경우 ab - ra - ca - da - br - a와 같이 분해됩니다.

입출력 예 #3
s="aaabbaccccabba"인 경우 aaabbacc - ccab - ba와 같이 분해됩니다.

 

시작 코드

using System;

public class Solution {
    public int solution(string s) {
        int answer = 0;
        return answer;
    }
}

 

나의 풀이

public class Solution {
    public int solution(string s) {
        int answer = 0; // 분해한 문자열의 개수
        int sameIdx = 0; // 같은 문자열 개수
        int diffIdx = 0; // 다른 문자열 개수
        char word = ' '; // 현재 단어
        bool start = true; // 시작지점 판단
        
        for(int i = 0; i < s.Length; i++)
        {
            if(start == true)
            {
                word = s[i];
                sameIdx++;
                start = false;
            }
            else
            {
                if(s[i] == word)
                {
                    sameIdx++;
                }
                else
                {
                    diffIdx++;
                }
            }
            
            if(sameIdx == diffIdx)
            {
                answer++;
                sameIdx = 0;
                diffIdx = 0;
                start = true;
            }
            if(i == s.Length - 1) { if(start == false) { answer++; } }
        }
        return answer;
    }
}

 

코드 분석

string타입의 문자열 s가 주어지며 코드가 시작됩니다. int형 변수 sameIdx와 diffIdx를 선언하고 char타입의 변수 word를 공백으로 선언합니다. 추가로 bool타입의 변수 start도 true로 선언해줍니다. 하나의 for문 안에 중첩 if else문을 작성해주고 바깥에서부터 살펴보면 for문은 i = 0부터 s의 길이까지 돌며 첫번째 if else문은 start가 true이면 word에 s[i]를 넣고, sameIdx를 올려준 뒤에 start를 false로 만들어 줍니다. 그게 아니면 다음 if else문으로 넘어갑니다. 이번에는 s[i]가 word랑 같다면 sameIdx를 올려주고 그게 아니면 diffIdx를 올려줍니다. 중첩 if else문을 빠져나오면 if문을 두개 더 만나게 됩니다. 첫번째 if문은 sameIdx와 diffIdx가 같다면 answer를 올리고 둘 다 0으로 만들어 준 뒤에 start를 true로 만들어줍니다. 두번째 if문은 중첩if문입니다. i가 s의 길이에서 1을 뺀 것과 같다면 내부의 if문에 들어가서 start가 false면 answer를 올려줍니다. 최종적으로 answer를 리턴하면서 코드는 종료됩니다.

 

풀이 설명

이번 문제는 직관적입니다. 주어진 문자열을 읽어 나가면서 첫번째 문자를 기준으로 같은 문자의 개수와 다른 문자의 개수가 같아지면 끊고 다시 해당 지점부터 같은 방법을 반복하는 구조입니다. 예시를 보면 이해가 훨씬 쉬운데 banana는 ba-na-na로 3개로 쪼개집니다.

 

먼저 s의 길이만큼 돌리는 for문 안에서 if else문은 시작지점을 판단하여 설정하는 작업을 합니다. else에는 시작지점이 아닐 때 수행하는 동작들입니다. s[i]와 word를 비교하여 같은 건지 아닌지 개수를 세는 역할을 합니다. if else문이 끝나면 다음 if문들로 같은문자 개수와 다른문자 개수가 같다면 자르고 넘어가는 다시 시작하는 동작을 해주고, 마지막 if문에서 for문의 마지막에 다다랐을 때에는 자르고 answer를 올려주도록 합니다.

 

<NEXT>

오늘은 "문자열 나누기" 문제를 풀어보았습니다. 다음에는 "대충 만든 자판" 문제를 다뤄보도록 하겠습니다. 감사합니다.