본문 바로가기
알고리즘/프로그래머스 PS

[프로그래머스][Level 2][Python] 문자열 압축

by 빛밤하늘 2021. 7. 26.
반응형

밑의 링크는 프로그래머스에서의 문제 링크입니다.

 

코딩테스트 연습 - 문자열 압축

데이터 처리 전문가가 되고 싶은 "어피치"는 문자열을 압축하는 방법에 대해 공부를 하고 있습니다. 최근에 대량의 데이터 처리를 위한 간단한 비손실 압축 방법에 대해 공부를 하고 있는데, 문

programmers.co.kr

 

 

 

 

 

 

 

 

주의해야 할 

압축할 문자의 개수 단위는 1개부터 문자열 s의 길이의 절반까지만 고려하면 됩니다.

문자열 s의 길이의 절반보다 큰 단위로는 압축이 되지 않습니다.

 

압축한 문자열 단위 개수가 1일 때는 생략해야 합니다.

 

매개변수로 주어지는 문자열 s의 길이가 1일 때의 경우를 고려해야 합니다.

처음 짠 코드에서는 위의 조건을 따로 고려하지 않은 채로 제출해보니까 테스트 1개를 통과하지 못했습니다.

 

 

 

생각한 풀이 과정

  1. 압축할 문자열 개수 단위는 1부터 문자열 s의 길이의 절반까지입니다. 그래서 1부터 문자열 s의 길이의 절반까지 반복해봅니다.
  2. 현재 압축 단위에서 압축한 결과를 저장할 변수를 하나 만들어줍니다.
  3. 과정 1에서 반복하고 있는 단위로 문자열 s를 자르고 난 후, 가장 최근의 단위 문자열을 저장하면서 자른 문자열들을 하나씩 반복해봅니다. 
  4. 현재 반복 중인 단위 문자열이 가장 최근의 단위 문자열과 같다면,  압축 횟수에 1을 더해줍니다.
  5. 현재 반복 중인 단위 문자열이 가장 최근의 단위 문자열과 같지 않다면, 압축 횟수와 가장 최근의 단위 문자열을 과정 2에서 만든 변수에 넣어줍니다.
  6. 한 압축 단위에서의 반복문이 끝나면 압축 후의 문자열의 길이를 이전까지 가장 짧은 압축 문자열의 길이와 비교해봅니다.
  7. 모든 반복문이 끝나면 가장 짧은 압축 문자열의 길이를 반환합니다.

 

 

 

 

 

 

 

 

제출한 파이썬 코드

# 압축할 문자열 s가 매개변수로 주어집니다.
# s의 길이는 1 이상 1,000 이하입니다.
# s는 알파벳 소문자로만 이루어져 있습니다.
def solution(s):
    # 압축 문자열 중 가장 짧은 길이를 저장할 변수를 선언합니다.
    shortest_len = None
    # 문자열 s의 길이를 저장하는 변수를 선언합니다.
    s_len = len(s)
    # 문자열을 압축할 때, 자를 단위 길이는 한 글자부터 시작하므로, 시작하는 단위 길이를 저장하는 변수를 선언합니다.
    unit_start = 1
    # 문자열을 압축할 때, 자를 단위 길이 중 최대 길이를 저장하는 변수를 선언합니다.
    # 자를 단위는 1부터 문자열 s의 길이의 절반까지 반복할 것이므로 s의 길이의 절반에 1을 더한 값을 저장하는 변수를 선언합니다.
    unit_end = s_len // 2 + 1

    # 문자열 s의 길이가 1이라면
    if s_len == 1:
        # 압축할 필요가 없으므로 가장 짧은 길이가 1입니다.
        shortest_len = 1
    # 문자열 s의 길이가 1보다 크다면
    else:
        # 자를 단위를 1부터 문자열 s의 길이의 절반까지 반복해봅니다.
        for unit in range(unit_start, unit_end):
            # 현재 자를 단위로 압축한 문자열을 저장할 변수를 선언합니다.
            cur_comp_result = ''
            # 문자열 s를 현재 자를 단위로 자른 뒤, 각 문자열을 차례로 반복해볼 때
            # 바로 이전의 압축한 글자 단위를 저장하는 변수를 선언합니다.
            # 처음에는 맨 앞 글자 단위로 초기화합니다.
            cur_comp_unit = s[:unit]
            # 현재 자를 단위로 압축한 글자 단위가 나타나는 횟수를 저장할 변수를 선언합니다.
            # 1번은 나타나므로 1로 초기화합니다.
            repeat_cnt = 1

            # 문자열 s를 unit 값의 인덱스부터 끝까지 현재 자를 단위로 잘라서 잘린 문자열들을 반복해봅니다.
            for idx in range(unit, s_len, unit):
                # 잘린 문자열들 중 현재 반복 중인 문자열을 저장하는 변수를 선언합니다.
                cur_char = s[idx:idx + unit]

                # 바로 이전의 압축한 글자 단위와 현재 반복 중인 문자열이 같다면
                if cur_comp_unit == cur_char:
                    # 압축 횟수에 1을 더해줍니다.
                    repeat_cnt += 1
                # 바로 이전의 압축한 글자 단위와 현재 반복 중인 문자열이 다를 때
                elif cur_comp_unit != cur_char:
                    # 압축 횟수가 1보다 크다면
                    if repeat_cnt > 1:
                        # cur_comp_result에 문자열로 변환한 압축 횟수를 넣어줍니다.
                        cur_comp_result += str(repeat_cnt)

                    # cur_comp_result에 바로 이전의 압축한 글자 단위를 넣어줍니다.
                    cur_comp_result += cur_comp_unit
                    # cur_comp_unit에 현재 반복 중인 문자열을 저장합니다.
                    cur_comp_unit = cur_char
                    # 다른 문자열이 나왔으므로 압축 횟수는 1로 만들어줍니다.
                    repeat_cnt = 1

            # 반복문을 다 돌고 나서 cur_comp_result와 repeat_cnt에 남은 값도 cur_comp_result에 넣어줘야합니다.
            # 압축 횟수가 1보다 크다면
            if repeat_cnt > 1:
                # cur_comp_result에 문자열로 변환한 압축 횟수를 넣어줍니다.
                cur_comp_result += str(repeat_cnt)

            # cur_comp_result에 바로 이전의 압축한 글자 단위를 넣어줍니다.
            cur_comp_result += cur_comp_unit
            
            # 현재 자를 단위로 압축한 문자열의 길이를 저장하는 변수를 선언합니다.
            cur_comp_len = len(cur_comp_result)

            # 아직 가장 짧은 것의 길이를 구하지 않았거나,
            # 앞서 구한 가장 짧은 것의 길이보다 현재 자를 단위로 압축한 문자열의 길이가 더 짧다면
            if shortest_len == None or cur_comp_len < shortest_len:
                # shortest_len에 현재 자를 단위로 압축한 문자열의 길이를 저장합니다.
                shortest_len = cur_comp_len

    # 압축한 문자열 중 가장 짧은 것의 길이를 반환합니다.
    return shortest_len

 

 

 

제출 결과

결과

 

 

 

 

 

 

 

 

느낀 점

공부 기록을 하는 김에 누군가 이 문제를 못 풀 때 참고하라고 쓰는 글인데...

글로만 설명하려고 하니까 너무 복잡해지고 쉽게 설명을 못하겠네요...

제가 봐도 너무 난잡합니다.

특히 이중 반복문을 글로 설명하려고 하니까 더 난잡해지는 것 같습니다. ㅜㅜ

그림을 그리고 나면 다시 올려야겠습니다.

 

 

 

※ 궁금한 부분, 이상한 점 및 오타는 댓글에 부탁드립니다.

※ 더 효율적이고 빠른 정답을 환영합니다.

반응형

댓글