프로그래밍/알고리즘

LCS(Longest Common Subsequence) + Java

sungjine 2022. 3. 9. 01:10
반응형

최장 공통부분 수열은(LCS, Longest Common Subsequence) 여러 개의 수열이 주어졌을 때 두 수열의 부분 수열이 되는 수열 중 가장 긴 수열을 찾는 방법이다.

 

구하는 방법은 하나의 수열을 순서대로 다른 수열의 모든 문자와 비교하여 같은지 비교하는데, 동적 계획법(DP)을 활용하여 문제를 푼다.

 

1. 만약 같다면 현재 비교하고 있는 [n][n] 번 위치의 문자 이전에 매치됐던 [n-1][n-1] 번 위치에 있는 문자에 더한다.

2. 만약 다르다면 비교하기 이전에 나왔던 가장 긴 길이를 갖도록 하기 위해서 [n][n-1] 위치의 값과 [n-1][n] 위치의 값을 비교하여 큰 값을 가진다.

3. 배열의 최종 위치의 숫자는 가장 긴 수열의 길이를 갖게 된다. 

 

예시: ABCD, BZDCD => BCD

 

예시에서 ABCD에서 B가 BZDCD에서 B와 매치됐을 때([2][1] 번 위치) A는 매치된 내용이 없기 때문에 1이 되고 ABCD의 C가 매치될 때는 B([2][1] 번 위치)에서 매치된 내용이 있기 때문에 2가 된다.

 

예시에서 ABCD의 B가 BZDCD의 Z와 비교할 때 매치하지 않기 때문에 [1][2] 번 위치와 [2][1] 번 위치의 값을 비교하여 큰 값인 1이 된다.

 

아래는 비교가 끝난 배열이다.

  0 B Z D C D
0 0 0 0 0 0 0
A 0 0 0 0 0 0
B 0 1 1 1 1 1
C 0 1 1 1 2 2
D 0 1 1 2 2 3

 

문제 : 백준 알고리즘 9251번 문제

문제 풀이 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        char[] a = br.readLine().toCharArray();
        char[] b = br.readLine().toCharArray();

        int aLen = a.length;
        int bLen = b.length;
        int[][] lcs = new int[aLen + 1][bLen + 1];

        for(int i = 1; i <= aLen; i++) {
            for(int j = 1; j <= bLen; j++) {
                if(a[i-1] == b[j-1]) {
                    lcs[i][j] = lcs[i-1][j-1] + 1;
                } else {
                    lcs[i][j] = lcs[i-1][j] > lcs[i][j-1] ? lcs[i-1][j] : lcs[i][j-1];
                }
            }
        }

        System.out.println(lcs[aLen][bLen]);
    }
}
반응형