akaSonny
[이것이 코딩테스트다] #36 편집 거리 본문
- 본 문제는 <이것이 코딩테스트다 with python (한빛미디어, 나동빈 저)> 에서 가져왔습니다.
문제
풀이
먼저, 두 개의 문자열을 비교하는 것이기 때문에 dp 테이블을 2차원으로 만들어야한다.
dp[i][j] --> A의 i번째까지의 문자열을 B의 j번째까지의 문자열로 바꿀 때의 편집 거리
간단하게, 예시에 나오는 "cat" 과 "cut" 으로 dp 테이블을 만들면 다음과 같다.
c | u | t | |
c | 0 | 1 | 2 |
a | 1 | 1 | 2 |
t | 2 | 2 | 1 |
(1, 1): "c"에서 "c"로 갈 때 필요한 연산 수 = 0
(1, 2): "c"에서 "cu"로 갈 때 필요한 연산 수 = 1
(1, 3): "c"에서 "cut"로 갈 때 필요한 연산 수 = 2
(2, 1): "ca"에서 "c"로 갈 때 필요한 연산 수 = 1
...
(3, 3): "cat"에서 "cut"로 갈 때 필요한 연산수 = 1
이제 이 dp 테이블을 보면서 점화식을 만들면 된다.
가장 먼저 생각해야 될 것은 글자가 같냐 / 같지 않냐로 나눈 것이다.
예를 들어, 'ca'에서 'cu'로 갈 때 1개의 연산이 필요한데, 'cat'에서 'cut'로 갈 때 추가적인 글자 t가 같기 때문에 더 이상의 연산이 필요없기 때문이다. 즉, 'ca' -> 'cu' 에 필요한 연산이나, 'cat' -> 'cut' 에 필요한 연산이 같다. 때문에 왼쪽 위칸의 연산 수를 그대로 가져오면 된다.
만약 같지 않다면?
이전의 연산 (즉, 왼쪽 위칸 / 왼쪽 칸 / 윗칸) 중 최솟값에 +1 을 해주면 된다.
이를 코드로 정리하면 다음과 같다.
a = input()
b = input()
# initialize the dp table
dp = [[0]*(len(b)) for _ in range(len(a))]
print(dp)
if a[0] == b[0]:
dp[0][0] = 0
else:
dp[0][0] = 1
for i in range(1, len(a)):
dp[i][0] = dp[0][0] + i
for j in range(1, len(b)):
dp[0][j] = dp[0][0] + j
# solve
for i in range(1, len(a)):
for j in range(1, len(b)):
if a[i] == b[j]:
dp[i][j] = dp[i-1][j-1]
else:
dp[i][j] = min(dp[i-1][j-1], dp[i][j-1], dp[i-1][j]) + 1
print(dp)
print(dp[-1][-1])
푸는 코드보다 dp 테이블 초기화 시키는 코드가 더 긴건.... 어쩔 수 없는 거겠징..?
'Study (Programming) > Coding Test' 카테고리의 다른 글
[이것이 코딩테스트다] #35. 못생긴 수 (0) | 2022.10.26 |
---|---|
파이썬 다익스트라 (Dijkstra) 알고리즘 (0) | 2022.05.11 |
[프로그래머스] 파이썬 python 정수 삼각형 풀이 (0) | 2022.02.24 |
파이썬으로 피보나치 수열 작성하기 (0) | 2022.01.26 |
파이썬 리스트 이진 탐색 (Binary Search) / bisect 모듈 (0) | 2022.01.04 |