문제 : LCS
Chan-Su Shin 님의 유튜브를 참고해서 작성했습니다.
문자열 = A B C D E ...
문자열 = X B C D X ...
각 문자열의 첫번째 문자를 번으로,
문자열의 번부터 번까지의 문자로 구성된 문자열을 ,
문자열의 번부터 번까지의 문자로 구성된 문자열을 라고 하자.
예를 들어, = A B C 이고, = X B C D 이다.
는 2개의 문자열을 인자로 받아서,
두 문자열의 LCS 길이를 반환한다.
예를 들어, 이다. ( A B C D ), ( X B C D )
을 구하기 위해서,
, 에 6번째 문자가 각각 새로 추가되었다고 생각 해보자.
두가지 경우가 있을 수 있다.
- 추가된 6번째 문자가 서로 같을 때
- 추가된 6번째 문자가 서로 같지 않을 때
A B C D E
X B C D X
일 때, = 3 이다.
그리고 6번째 문자가 새로 추가되었다.
A B C D E + P
X B C D X + P
새로 추가된 두 문자가 같기 때문에,
LCS의 길이는 1 증가한다.
이렇게 쓸 수도 있겠다.
= + 1
그리고 이것은 두 문자열의 길이와 관계없이 성립할 것이다.
의 번째 문자와, 의 번째 문자가 같을 때,
+ 1
이때는 3가지 경우가 생긴다.
3가지 경우에서,
LCS의 길이가 증가하는 경우를 찾기위해 해 주어야 할 질문은
어떤 문자열에 새로운 문자를 추가했을 때 LCS 길이가 증가하나요?
이다.
( 3번 처럼 길이가 증가하지 않을 수도 있다. )
이 두 가지 경우의 LCS길이 중 큰 값이
이다.
얘도 이렇게 써줄 수 있고,
= 와 중에 큰 값
마찬가지로, 이렇게도 써 줄 수 있다.
의 번째 문자와, 의 번째 문자가 같지 않을 때,
LCS가 2차원 배열이라면 어떨까?
두 문자열의 문자를 차례로 비교하면서,
위에서 설명한 것처럼
같을 경우와 다를 경우를 나누어 갱신해준다.
[ 전체 코드 ]
import sys
sequence1 = sys.stdin.readline().rstrip()
sequence2 = sys.stdin.readline().rstrip()
n = len(sequence1)
m = len(sequence2)
LCS = [[0] * (m+1) for _ in range(n+1)]
for i in range(1, n+1):
s1 = sequence1[i-1]
for j in range(1, m+1):
s2 = sequence2[j-1]
if s1 == s2:
LCS[i][j] = LCS[i-1][j-1] + 1
else:
LCS[i][j] = max(LCS[i-1][j], LCS[i][j-1])
sys.stdout.write(f'{LCS[n][m]}')