LeeTaes 공부노트

[프로그래머스/C++ 문제 풀이] Lv. 1 - 문자열 나누기 본문

코딩테스트/프로그래머스 (Lv. 1)

[프로그래머스/C++ 문제 풀이] Lv. 1 - 문자열 나누기

리태s 2024. 7. 20. 13:48
728x90
반응형

문제 설명

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

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

문자열 s가 매개변수로 주어질 때, 위 과정과 같이 문자열들로 분해하고, 분해한 문자열의 개수를 return 하는 함수 solution을 완성하세요.

제한 사항

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

입출력 예

 

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

 

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

 

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


문제 풀이

저는 이번 문제를 카운트 수만 조정해서 푸는 방식(1), 실제 문자열을 나누는 방식(2)으로 해결하였습니다.

 

문제의 이름은 문자열 나누기지만 결국 x와 x가 아닌 수를 비교하며 문자열을 나눴을 때 나눠진 문자열의 개수를 구하면 되기에 실제로 문자열을 나눌 필요는 없이 전체 문자를 순회하며 xCnt, notXCnt를 체크만 해도 상관없으며, 시간복잡도를 낮출 수 있습니다.

 

개인적으로 그리 어렵지 않은 난이도라고 생각하지만, 마지막 남은 문자를 카운트해주지 않아서 1회 오답 처리를 받게 되었습니다.

정답 코드 1 (문자 카운트)

더보기
#include <string>
#include <vector>

using namespace std;

int solution(string s) {
    int answer = 0;
    
    // 문자 x 초기화 (처음에는 첫 번째 문자)
    char x = s[0];
    // x 카운트
    int xCnt = 1;
    // not x 카운트
    int notXCnt = 0;
    
    for (int i = 1; i < s.size(); i++)
    {
        // 만약 현재 인덱스의 문자와 x가 동일하다면?
        if (s[i] == x)
        {
            // x카운트 증가
            xCnt++;
        }
        // 만약 현재 인덱스의 문자와 x가 다르다면?
        else
        {
            // not x 카운트 증가
            notXCnt++;
        }
        
        // x와 x가 아닌 카운트가 동일하다면?
        if (xCnt == notXCnt)
        {
            // 결과 값 증가
            answer++;
            // 카운트 초기화
            xCnt = 0;
            notXCnt = 0;
            // x값 추가
            x = s[i + 1];
        }
    }
    
    // 만약 남은 문자가 존재한다면? (카운트가 초기화가 안된 상황)
    if (xCnt > 0)
    {
        // 결과 값 증가
        answer++;
    }
    
    return answer;
}

정답 코드 2 (문자 나누기)

더보기
#include <string>
#include <vector>

using namespace std;

int solution(string s) {
    int answer = 0;

    // 이전 문자 저장 (처음에는 첫 번째 문자)
    char Prev = s[0];

    // x와 x가 아닌 수를 저장합니다.
    int xCnt = 1;
    int notXCnt = 0;

    // 순회 인덱스
    int idx = 1;

    while (true)
    {
        // 만약 s가 1개의 문자로만 이루어졌다면?
        if (s.length() == 1)
        {
            // 문자열 s를 비우고 결과 값을 1 증가시키고 종료합니다.
            s.clear();
            answer++;
            break;
        }

        // 인덱스가 범위를 초과했다면 종료합니다.
        if (idx >= s.length()) break;

        // 만약 prev와 현재 인덱스의 문자가 같은 경우
        if (Prev == s[idx])
        {
            // x 카운트 증가
            xCnt++;
        }
        // 만약 prev와 현재 인덱스의 문자가 다른 경우
        else 
        {
            // x가 아닌 카운트 증가
            notXCnt++;
        }

        // 만약 양쪽 카운트가 동일하다면?
        if (xCnt == notXCnt)
        {
            // 문자열을 분리합니다.
            s = s.substr(idx + 1);

            // 카운트를 증가시킵니다.
            answer++;
            // Prev를 다시 설정하고 x와 x가 아닌 카운트를 초기화합니다.
            Prev = s[0];
            xCnt = 1;
            notXCnt = 0;

            // 인덱스 조정
            idx = 1;
        }
        else
        {
            idx++;
        }
    }

    // 만약 남은 문자열이 존재한다면 결과를 추가합니다.
    if (!s.empty())
        answer++;

    return answer;
}
728x90
반응형