문자열 압축

zzwwoonn·2022년 6월 10일
0

Algorithm

목록 보기
50/71

첫 번째 풀이

for i in range(1, len(s)//2+1):
        makeStrList.append([s[j:j+i] for j in range(0, len(s), i)])

    for oneList in makeStrList:
        cnt = 0
        print("oneList = ", oneList)
        for oneVal in oneList:
            print("oneVal = ", oneVal)
            listX = list(oneVal)
            lenX = len(listX)
            setX = set(listX)
            
            if len(setX) != 1:
                cnt += lenX
            
            else:
                cnt += 2
            print("cnt = ", cnt) 
        answer = min(cnt , answer)

어렵다. 처음엔 문제를 잘못 이해해서 시간이 좀 걸렸다고 쳐도...
(5번 테스트 케이스를 보고 문제를 잘못 이해했다는 걸 알았다)

입력 문자열을 자를 숫자(N : 1~len(s)) 까지 다 잘라서 배열에다가 넣어둔다. 그걸 꺼내서 쓸거고, 집합을 이용해서 중복을 제거해준다. 그럼 어떤게 중복이고 최대로 줄였을 때 남는 문자가 뭔지 알 수 있다.

근데 이렇게 푸는거 아니다. 그냥 틀렸다.

두 번째 풀이

s = "aabbaccc"

# 1. 문자열 자르기 => 이거 잘라놓은걸로 한번 loop 진행, 한번의 단계(process)
answer = 1000
answer = 0

for N in range(1, len(s)//2+1):
    # 자르는건 최대 절반
    sliceList = [s[i:i+N] for i in range(0, len(s), N)]
    # N개로 잘라서 배열에 저장
    print(N, "개로 잘라서 배열 만들기")
    print("sliceList = ", sliceList)
    
    resultStr = ""
    cnt = 1

    for i in range(0, len(sliceList)-1):
        tmp = sliceList[i]
        # 비교할 대상 하나 정하기
        # 첫 번째 비교 대상 => aa
        print("i = ", i, " tmp = ", tmp)

        cnt = 1

        for j in range(i+1,len(sliceList)):
            print("j = ", j, " 비교할 문자열 = ", sliceList[j])
            if tmp == sliceList[j]:
                print("똑같은 거네?")
            # 바로 다음 문자열(bb)이랑 같은거면?
                cnt += 1
                print("cnt = ", cnt)

            else:
                # aa랑 bb랑 달라 -> 1aa
                print("다른거네")
                break
        
        if cnt == 1:
            resultStr += tmp
        else:
            resultStr += str(cnt) + tmp
        
        print("resultStr = ", resultStr)
        answer = min(answer, len(resultStr))

정석 풀이랑 얼추 비슷하다. 근데 틀린다.
aabbcacc 를 넣었을 때 최종 압축된 문자열이 2a2a2b2b~ 이런식으로 나온다.

어디까지 비교(process)를 했는지 기억을 하지 못한다. 로직 자체가 틀렸다.

세 번째 풀이

answer = 1000

if len(s) == 1:
    answer = 1
    
for N in range(1, len(s)):
    # # 자르는건 최대 절반
    # sliceList = [s[i:i+N] for i in range(0, len(s), N)]
    # # N개로 잘라서 배열에 저장
    # print(N, "개로 잘라서 배열 만들기")
    # print("sliceList = ", sliceList)
    
    resultStr = ""
    cnt = 1
    tmp = s[:N]

    for i in range(N, N+len(s), N):
        # 시작점을 N으로 두면 돼
        if tmp == s[i:i+N]:
            # i에서 N만큼 건너 뛰면서 보면 돼
            # 만약에 같으면? 
            cnt += 1
            
        else:
            # 만약에 다르면? 
            if cnt == 1:
                # 처음들어왔단 말
                resultStr += tmp
            else:
                # 지금까지 같은게 여러 개 있었단 말
                resultStr += str(cnt) + tmp
            tmp = s[i:i+N] 
            # 다음 문자열로 바꿔줘
            cnt = 1
            # cnt 초기화

    answer = min(answer, len(resultStr))
print(answer)

두 번째 코드와의 차이점 즉, 핵심은

 # 자르는건 최대 절반
sliceList = [s[i:i+N] for i in range(0, len(s), N)]
# N개로 잘라서 배열에 저장
# print(N, "개로 잘라서 배열 만들기")
# print("sliceList = ", sliceList)

이렇게 해서 

for i in range(0, len(sliceList)-1):
	tmp = sliceList[i]

이런식으로 tmp 를 지정해주면서 프로세스(비교)를 진행하려고 했는데, 세 번째 코드에서는 길이가 확 준다.

tmp = s[:N]

처음 for 문을 돌 때 위 코드 한 줄이면 모든게 해결 된다. 위의 코드로 초기값을 잡아주고 그 다음 문자열이랑 비교할 때는?

for i in range(N, N+len(s), N):
    # 시작점을 N으로 두면 돼
	if tmp == s[i:i+N]:
    	# i에서 N만큼 건너 뛰면서 보면 돼
        # 만약에 같으면? 
       	cnt += 1

비교 과정이 끝난 경우에 tmp를 다음 문자열로 바꿔줘야 한다.

tmp = s[i:i+N] 
# 다음 문자열로 바꿔줘
cnt = 1
# cnt 초기화

예외

입력 문자열의 길이가 1인경우 for loop 자체를 돌지 않기 때문에 answer가 1000이다. 예외처리 해준다.

풀이 과정

0개의 댓글