프로그래머스 – 문자열나누기 문제 Python

프로그래머스 문제풀이

문제

문제설명

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

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

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

제한사항

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

입출력 예

sresult
“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와 같이 분해됩니다.

문제해석과정

  1. 문자열 s를 분해하려 한다.
  2. 문자열을 왼쪽에서 오른쪽으로 순차적으로 읽으며, 첫 글자를 x라고 지정한다.
  3. x와 x가 아닌 문자를 각각 횟수를 센다.
  4. 처음으로 두 횟수가 같아지면 문자열을 분리한다.
  5. 분리한 문자열을 제외하고 남은 부분으로 2,3,4를 반복해준다.
  6. 남은 부분이 없거나 두 횟수가 다르더라도 더 이상 읽을글자가 없다면 문자열로 분리하고 종료한다.
  7. 분리된 문자열 갯수를 출력한다.

위 같은 문제 및 제한사항을 해석하고 문제풀이를 시작하면 됩니다.

나의 풀이

이번 문제는 while을 사용하여 문자열이 0과 같거나 작으면 종료

문자열의 요소를 제거하여 줄여가기위해 리스트로 변환

그리고 지정문자와 지정문자수, 비교문자수를 담을 리스트를 정의

인덱스는 무조건 1부터 시작(0은 첫글자이므로… 한번이라도 반복을 줄이겠다는 노력… >_< )

당연히 지정문자수도 1부터 시작

테스트 31번이 막히셨다면 아래 소스 8~10번 줄을 참고하시면 됩니다.

테스트 31번 케이스는 아마도 문자열이 하나일때인 것 같아요.

def solution(s):
    answer = 0
    SL=list(s)
    CntL=["",1,0]       #지정문자, 지정문자수, 비교문자수
    index = 1           #인덱스
    
    while len(SL) > 0:
        if len(SL) == index:     #두 횟수가 다르지만 더이상 읽을 글자가 없을때 
            answer += 1          #분리된 문자열 수 +1
            break                #반복문 종료
        CntL[0]=SL[0]            #첫글자를 지정문자로 지정
        if SL[index] == CntL[0]: #글자와 지정문자가 같다면
            CntL[1] += 1         #지정문자수 +1
            index += 1           #인덱스 +1
        else:                    #글자와 지정문자가 다르면
            CntL[2] += 1         #비교문자수 +1
            if CntL[1] == CntL[2]:                #지정문자수와 비교문자수가 같다면
                del SL[:index+1]                  #현재인덱스까지의 요소 제거
                answer += 1                       #분리된 문자열 수 +1
                index, CntL[1], CntL[2] = 1,1,0   #인덱스, 지정문자수, 비교문자수 초기화
            else:                                 #지정문자수와 비교문자수가 다르면
                index += 1                        #분리된 문자열 수 +1
    return answer

다른 사람의 풀이

이번 문제는 저와 비슷하지만 더 잘(?)코딩했다고 느껴지는 풀이를 가져와봤어요.

문제해결 후에 다른분들 풀이보면서 시작부터 방향을 잘못잡았다고 느낀게 저는 요소를 제거하고 매번 0인덱스부터 새로 돌리겠다는 생각으로 소스를 짰거든요.

근데 다른분들은 그냥 문자열 요소하나하나를 바로 확인하고 카운팅하는식으로 푸셨더라구요.

그래서 제가 생각을 좀 잘못했구나라는 걸 느꼈어요.

문제는 결국 해결하긴 했지만… 굳이 리스트변환하거나 요소삭제 후 0인덱스부터 다시 검색해 줄 필요가 없었는데

이렇게 하나 또 배워갑니다.(머리가 나쁘면 손발이 고생… ㅠㅠ)

def solution(s):
    answer = 0
    t = ["", 0, 0]
    for i in s:
        if t[0] == "":
            t[0] = i
            t[1] += 1
        else :
            if t[0] == i:
                t[1] += 1
            else :
                t[2] += 1
            if t[1] == t[2]:
                answer += 1
                t = ["", 0, 0]
    if t != ["", 0, 0]:
        answer += 1
    return answer

관련 링크

문제해결과정에서 기초가 부족하다고 느껴지시면 아래 정리 글을 참고해주세요.