..

최장 공통 부분 수열(LCS)과 문자열(LCSubstring)

최장 공통 부분 수열(LCS: Longest Common Subsequence)

  • 여러 수열(주로 문자열)중 순서를 유지하면서 공통으로 존재하는 가장 긴 부분 수열을 찾는다

    부분 수열

    • 문자열 일부를 건너뛰어도 되지만, 순서는 유지되어야 함

    예시

    • Git의 diff 유틸리티, 문서 비교 / 버전 관리, DNA 서열 분석

코드 리뷰

def lcs(a, b):
    n, m = len(a), len(b)
    dp = [[0] * (m+1) for _ in range(n+1)]

    for i in range(1, n+1):
        for j in range(1, m+1):
            if a[i-1] == b[j-1]:
                dp[i][j] = dp[i-1][j-1] + 1
            else:
                dp[i][j] = max(dp[i-1][j], dp[i][j-1])

    return dp[n][m]

print(lcs("ABCBDAB", "BDCAB"))  # 출력: 4

 

최장 공통 부분 문자열(LCSubstring: Longest Common Substring)

  • 여러 문자열에서 연속적으로 일치하는 가장 긴 부분 문자열을 찾는다

    부분 문자열

    • 연속된 문자들의 묶음

    예시

    • 검색어 자동완성, 표절 탐지 도구, 키워드 일치 분석

코드 리뷰

def lcsubstring(a, b):
n, m = len(a), len(b)
dp = [[0] * (m+1) for _ in range(n+1)]
max_len = 0

for i in range(1, n+1):
    for j in range(1, m+1):
        if a[i-1] == b[j-1]:
            dp[i][j] = dp[i-1][j-1] + 1
            max_len = max(max_len, dp[i][j])
        else:
            dp[i][j] = 0  # 연속 조건이 깨짐

return max_len

print(lcsubstring("ABCDEF", "ZCDEK"))  # 출력: 3

차이점

항목 LCS (수열) LCSubstring (문자열)
연속 여부 연속되지 않아도 됨 반드시 연속되어야 함
순서 유지 필요함 필요함
결과 가장 긴 공통 부분 수열 가장 긴 연속된 문자열
예시 ABCBDAB vs BDCAB → BCAB ABCDEF vs ZCDEK → CDE

시간 복잡도

문자열과 수열(n은 첫번째, m은 두번째 문자열)

  • O(n x m): 두 문자열을 비교하는 모든 경우의 수