문자열 압축 [프로그래머스 60057]

오준혁·2023년 5월 26일
0

알고리즘

목록 보기
21/29

문제


프로그래머스 [문자열 압축 60057]
https://school.programmers.co.kr/learn/courses/30/lessons/60057

풀이


첫번째 풀이

슬라이싱을 이용하여 설정해둔 문자열과 다음 검사 문자열과 비교하여 반복되는 횟수와 해당 단위를 최종 문자열에 추가해주는 코드를 반복문을 이용하여 작성하면 된다.

key point

  • 침착하게 단위의 크기를 늘려가며 문자열을 검사할 것
  • 압축된 문자열 형성하는 법을 잘 생각할 것

! 어려웠던 점

  • 문제를 처음 봤을 때 고려해야할 사항이 많다고 생각해서 코드를 처음 작성할 때 망설임이 많았었다. 그냥 생각하는 대로 코드를 작성하면 해결되는 문제였다.
  • 다음 검사할 문자열을 어떻게 참조할까를 고민했는데 자르는 단위의 길이만큼 더 더하여 슬라이싱을 하면 됐었다.

두번째 풀이

두번째는 프로그래머스 제출 답안을 보다가 제일 추천을 많이 받은 코드인데 파이썬의 장점이 정말 잘 이용한 코드라고 생각해서 가져왔다.

  1. 리스트 컴프리헨션을 정말 잘 이용한다.
    난 아직 파이썬을 c언어 배운대로 작성하는 느낌이라 파이쏘닉한 코드작성법에 익숙하지 않은데 이런 코드를 보니 느낀 점이 많았다.
  2. zip 내장 함수를 사용하여 검사할 문자열들을 참조하였다.
    정말 기발하고 파이썬 내장함수를 잘 이용한 예시라고 생각이 되었다.

코드


1

def solution(s):
    answer = len(s)     # 압축이 안되는 경우를 생각하여 답을 문자열 길이로 설정
    for step in range(1, len(s) + 1):
        compressed = '' # 압축할 문자열 선언
        count = 1       # 몇 번 나오는 지 저장할 수
        prev = s[0:step]# 반복되는 지 검사 문자열
        for j in range(step, len(s), step):
            if prev == s[j:j + step]:   # 다음에 똑같으면 
                count += 1              # count ++
            else:
                if count >= 2:          # 2번 이상 반복하면
                    compressed += str(count) + prev # count + prev 압축 문자열에 추가
                else:                   # 아니면
                    compressed += prev              # prev만 추가
                prev = s[j:j + step]                # 다음 prev를 마지막 검사 문자열로 설정
                count = 1                           # count를 1로 설정
                # 마지막에 추가되지 않은 문자열 추가
        if count >= 2:
                compressed += str(count) + prev     
        else:
            compressed += prev
        answer = min(answer, len(compressed))       # 가장 짧은 문자열로 설정
    return answer
    

2

def compress(text, tok_len):
    words = [text[i:i+tok_len] for i in range(0, len(text), tok_len)] # 토큰 길이대로  문자열을 나눈 문자열들의 리스트
    res = []
    cur_word = words[0] #초기 문자열 설정
    cur_cnt = 1
    for a, b in zip(words, words[1:] + ['']):   # 한 index뒤 의 문자열과 비교하며 반복문 수행
        if a == b:                              # 같으면 cnt ++
            cur_cnt += 1
        else:
            res.append([cur_word, cur_cnt])     # 다르면 res에 word와 cnt 추가
            cur_word = b                        # word, cnt 초기화
            cur_cnt = 1
    return sum(len(word) + (len(str(cnt)) if cnt > 1 else 0) for word, cnt in res)  #압축 문자열 종합

def solution(text):
    # 1부터 전체 문자열의 절반, 문자열 길이 만큼의 리스트를 선언 후 반복적으로compress 함수 선언 후 최솟값 반환
    return min(compress(text, tok_len) for tok_len in list(range(1, int(len(text)/2) + 1)) + [len(text)])   

0개의 댓글