๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Data Structure๐Ÿงถ

LCS ์ตœ์žฅ ๊ณตํ†ต ๋ถ€๋ถ„ ์ˆ˜์—ด DP

by Jouureee 2021. 3. 1.

๐Ÿ”˜์ตœ์žฅ ๊ณตํ†ต ๋ถ€๋ถ„ ์ˆ˜์—ด ์ด๋ž€? (LCS, Longest Common Subsequence)


๋‘๊ฐœ์˜ ๋ฌธ์ž์—ด์ด ์ฃผ์–ด์กŒ์„ ๋•Œ ๊ณตํ†ต์œผ๋กœ ๋“ค์–ด ์žˆ๋Š” ๋ถ€๋ถ„ ์ˆ˜์—ด ์ค‘ ๊ฐ€์žฅ ๊ธด ์ˆ˜์—ด์„ ๋งํ•œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด

ABCDE์™€ ACDFG์ด ์ฃผ์–ด์กŒ๋‹ค๋ฉด ๋‘ ๋ฌธ์ž์—ด์˜ ๊ณตํ†ต ๋ถ€๋ถ„ ์ˆ˜์—ด์€ 

{A}, {C}, {D}, {AC}, {AD}, {ACD} ์ด๊ณ  LCS๋Š” ๋ฐ”๋กœ {ACD}๋ฅผ ๋งํ•œ๋‹ค. 

 

- LCS์™€ LCS (์ตœ์žฅ ๊ณตํ†ต ๋ถ€๋ถ„ ์ˆ˜์—ด๊ณผ ์ตœ์žฅ ๊ณตํ†ต ๋ถ€๋ถ„ ๋ฌธ์ž์—ด)

์‚ฌ์‹ค LCS๋Š” ๋œป์ด ๋‘๊ฐ€์ง€๋‹ค ..! 

LCS( Longest Common Subsequence) ์ด ์žˆ๊ณ 

์ตœ์žฅ ๊ณตํ†ต ๋ถ€๋ถ„ ๋ฌธ์ž์—ดLCS( Longest Common Substring) ์ด ์žˆ๋‹ค. 

์œ„ ๋‘ ๋ฌธ์ž์—ด ABCDE์™€ ACDFG์— ๋Œ€ํ•ด์„œ ์ตœ์žฅ ๊ณตํ†ต ๋ถ€๋ถ„ ์ˆ˜์—ด๋Š” {ACD}์ง€๋งŒ ์ตœ์žฅ ๊ณตํ†ต ๋ถ€๋ถ„ ๋ฌธ์ž์—ด์€ ์—ฐ์ด์–ด์ ธ์•ผ ํ•œ๋‹ค. 

๋”ฐ๋ผ์„œ {CD} ์ด๋‹ค. 

 

 

 

โ˜‘๏ธ ์ ‘๊ทผ ๋ฐฉ๋ฒ•


์ด ๋ฌธ์ œ๋Š” DP(dynamic programming)์œผ๋กœ ์ ‘๊ทผํ•˜์—ฌ ์ ํ™”์‹์œผ๋กœ ํ’€๋ฉด ๊ฐ„๋‹จํ•˜๊ฒŒ ํ’€ ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. 

์—ฌ๊ธฐ์„œ ๋ฐ”๋กœ

DP๋กœ ๋ฌธ์ œ ํ’€๊ธฐ ์œ„ํ•œ ์กฐ๊ฑด

 

  1. ์ž‘์€ ๋ฌธ์ œ๊ฐ€ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ผ์–ด๋‚œ๋‹ค.
  2. ๊ฐ™์€ ๋ฌธ์ œ๋Š” ๊ตฌํ•  ๋•Œ๋งˆ๋‹ค ์ •๋‹ต์ด ๊ฐ™๋‹ค.

 

 

 

์ฆ‰ ํฐ ๋ฌธ์ œ๋ฅผ ํ’€ ๋•Œ ์ž‘์€ ๋ฌธ์ œ๋กœ ๋‚˜๋ˆ ์„œ ํ‘ธ๋Š”๋ฐ ์ž‘์€ ๋ฌธ์ œ์™€ ํฐ ๋ฌธ์ œ ํ‘ธ๋Š” ๋ฐฉ๋ฒ•์ด ๊ฐ™๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. 

 

 

 

๐Ÿ‘‍๐Ÿ—จLCS ์ ํ™”์‹


LCS์˜ ์ ํ™”์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

 

์˜ˆ๋ฅผ ๋“ค์–ด 

ABCDE์™€ ACDFG ๋‘ ๋ฌธ์ž์—ด์ด ์žˆ๋‹ค๊ณ  ํ•˜์ž

 

X : ABCDE

Y : ACDFG

 

X์˜ ๋งˆ์ง€๋ง‰ ๋ฌธ์ž(E)๋ฅผ ํ•˜๋‚˜ ์ง€์›Œ๋ณด์ž ๊ทธ๋Ÿฌ๋ฉด ABCD๊ฐ€ ๋  ๊ฒƒ์ด๋‹ค. ๊ทธ๋ž˜๋„ LCS์—๋Š” ์ƒ๊ด€์ด ์—†๋‹ค. 

X์˜ ๋งˆ์ง€๋ง‰ ๋ฌธ์ž(D)๋ฅผ ํ•˜๋‚˜ ๋” ์ง€์šฐ๋ฉด ABC๊ฐ€ ๋˜๊ณ  ์ด๋ฒˆ์—๋Š” LCS ๊ธธ์ด๊ฐ€ ํ•˜๋‚˜ ์ค„์–ด๋“ ๋‹ค. 

 

์ฆ‰ ์ˆ˜์—ด์˜ ๋งˆ์ง€๋ง‰ ๋ฌธ์ž๋ฅผ ์ œ๊ฑฐํ•˜๋ฉด  1. LCS ๊ธธ์ด๊ฐ€ ๊ทธ๋Œ€๋กœ๋‹ค 2. LCS ๊ธธ์ด๊ฐ€ ์ค„์–ด๋“ ๋‹ค. ๋‘๊ฐ€์ง€ ๊ฒฝ์šฐ๋ฅผ ๊ฐ€์ง„๋‹ค. 

 

c[i, j]๋ฅผ Xi์™€ Yi์˜ ์ตœ์žฅ ๊ณตํ†ต ๋ถ€๋ถ„ ์ˆœ์—ด์ด๋ผ๊ณ  ํ•˜์ž. i์™€ j๋Š” ๋ฌธ์ž์—ด์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ธ๋ฑ์Šค๋‹ค.

 

i์˜ ๋ฒ”์œ„  1 <= i <= 5

j์˜ ๋ฒ”์œ„ 1<= j <=5

 

1) i = 0 or j = 0 ์ธ๊ฒฝ์šฐ 

๋ฌธ์ž์—ด ๊ธธ์ด๊ฐ€ 0 ์ด๋ฉด LCS ๋„ 0์ด ๋  ์ˆ˜ ๋ฐ–์— ์—†๋‹ค.

 

2) i != 0 and j !=0 ์ด๊ณ   Xi != Yj ์ธ ๊ฒฝ์šฐ

 

์˜ˆ๋ฅผ ๋“ค์–ด 

X : ABCDE, Y : ACDFG ์ผ ๋•Œ

X์˜ ๋งˆ์ง€๋ง‰ ๋ฌธ์ž E์™€ Y์˜ ๋งˆ์ง€๋ง‰ ๋ฌธ์ž G๊ฐ€ ๋‹ค๋ฅด๋‹ค. 

๊ทธ๋Ÿฌ๋ฉด ๋‘๊ฐ€์ง€ ๊ฒฝ์šฐ๋กœ ๋‚˜๋ˆ  ์ƒ๊ฐ ํ•ด ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

1) LCS๊ฐ€ E๋กœ ๋๋‚˜๋Š” ๊ฒฝ์šฐ

2) LCS๊ฐ€ G๋กœ ๋๋‚˜๋Š” ๊ฒฝ์šฐ 

 

1) LCS๊ฐ€ E๋กœ ๋๋‚˜๋Š” ๊ฒฝ์šฐ G๋Š” ์ตœ์žฅ ๊ณตํ†ต ์ˆ˜์—ด์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ 

c[i, j] = c[i, j - 1]๋กœ๋„ ์ƒ๊ฐ ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.  

 

1) LCS๊ฐ€ G๋กœ ๋๋‚˜๋Š” ๊ฒฝ์šฐ ๋ฐ˜๋Œ€๋กœ E๊ฐ€ ์ตœ์žฅ ๊ณตํ†ต ์ˆ˜์—ด์„ ๋งŒ๋“œ๋Š”๋ฐ ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ง€์›Œ๋„ ์ƒ๊ด€ ์—†๋‹ค.

๋”ฐ๋ผ์„œ c[i -1, j] = c[i, j]

 

์šฐ๋ฆฌ๋Š” ์ตœ์žฅ ๊ณตํ†ต ์ˆ˜์—ด์„ ์›ํ•˜๋ฏ€๋กœ c[i, j] = max(c[i, j - 1], c[i -1, j] )์˜ ๊ฐ’์„ ๊ฐ€์งˆ ๊ฒƒ์ด๋‹ค.

 

 

2) i != 0 and j !=0 ์ด๊ณ   Xi == Yj ์ธ ๊ฒฝ์šฐ

์˜ˆ๋ฅผ ๋“ค์–ด ASC ์™€ AEC ๋‘ ๋ฌธ์ž์—ด์˜ ๋งˆ์ง€๋ง‰ ๊ฐ’(C)์ด ๊ฐ™๋‹ค๋ฉด C๋Š” ์ด๋ฏธ ์ตœ์žฅ ๊ธธ์ด ๋ฌธ์ž์—ด์˜ ์›์†Œ๋กœ ํ™•๋ณดํ•ด ๋‘๊ณ  C๋ฅผ ์ œ์™ธํ•œ 

AS์™€ AE์˜ ๋น„๊ต ๊ณผ์ •์„ ๊ฑฐ์น˜๊ณ  ์‹ถ์„ ๊ฒƒ์ด๋‹ค.

๊ทธ๋Ÿฌ๋ฏ€๋กœ c[i, j] = c[i - 1][j - 1] + 1 ์ด ๋œ๋‹ค. 

 

 

๐Ÿ”ณ ํ–‰๋ ฌ์„ ์ด์šฉํ•œ ๊ฐ’ ๊ณ„์‚ฐ 


 

์‚ฌ์‹ค ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์‹œ๊ฐ„์— ์ด๋ ‡๊ฒŒ ๋ฐฐ์› ์—ˆ๋‹ค ๋ฐ•์˜ํ›ˆ ๊ต์ˆ˜๋‹˜์˜ ๋ฒ„๋ฒ…๊ฑฐ๋ฆผ๊ณผ ํ•จ๊ป˜ ๋ง์ด๋‹ค.

๊ทธ๋ž˜์„œ ์ด ๋ฐฉ์‹์ด ๋” ์ต์ˆ™ํ•˜๊ณ  ์ด๋ฅผ dp ์ ํ™”์‹ ์† ๋Œ€๊ธฐ ์–ด๋ ต๋‹ค ๋Š๊ปด์ง€๋ฉด ํ–‰๋ ฌ๋กœ ๋จผ์ € ์นœ๊ทผํ•ด์ง€๋Š” ๊ฒƒ์ด ๋” ์ข‹์„ ๋“ฏ ํ•˜๋‹ค.

 

์˜ˆ์‹œ๋กœ ๋“ค์—ˆ๋˜ ABCDE์™€ ACDFG๋ฅผ ํ–‰๋ ฌ์— ๊ฐ’์œผ๋กœ ๋„ฃ์–ด์ฃผ์—ˆ๋‹ค.

 

 

์ด์ฐจ์› ํ–‰๋ ฌ๋กœ ๋งŒ๋“ค๊ณ  0๋ฒˆ์งธ ์ธ๋ฑ์Šค๋“ค์€ 0์œผ๋กœ ์ดˆ๊ธฐํ™” ์‹œ์ผœ์ค€๋‹ค. 

 

X ๋ฌธ์ž์—ด์— ๋Œ€ํ•ด ๊ฒ€์‚ฌ๋ฅผ ์‹œ์ž‘ํ•˜๋Š”๋ฐ A ๋ฌธ์ž์—ด์ด ๊ฐ™๋‹ค!! ๊ทธ๋Ÿฌ๋ฉด ์ขŒ์ธก๊ฐ’ 0๊ณผ ์œ„์ชฝ ๊ฐ’ 0 ์ค‘ ํฐ ๊ฐ’ (๊ฒฐ๊ตญ 0)์— +1์„ ํ•ด์ค€๋‹ค.

 

 

X์˜ i =1 ์ผ๋•Œ ์ฆ‰ A ์›์†Œ์— ๋Œ€ํ•ด ์ˆ˜ํ–‰ํ•ด์ฃผ๋ฉด 

 

์ด๋ ‡๊ฒŒ ํ•œ ์ค„์ด ์™„์„ฑ์ด ๋˜๊ฒ ๋‹ค 

 

B๋„ ๋งˆ์นœ๊ฐ€์ง€๋กœ ํ•ด์ฃผ๊ณ  C๋ฅผ ๋ณด๊ฒŒ ๋˜๋ฉด 

์ฒ˜์Œ A ํ•œ ๊ฒƒ ์ฒ˜๋Ÿผ C ์—ญ์‹œ ์ž์‹ ์˜ ์ขŒ์ธก๊ฐ’(1)๊ณผ ์šฐ์ธก ๊ฐ’(1) ์ค‘ ํฐ ๊ฐ’์— +1์„ ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด 2๊ฐ€ ๋œ๋‹ค 

 

๋ฐ˜๋ณต์ ์ธ ์ผ๋“ค์„ +1์”ฉ ์ฆ๊ฐ€์‹œํ‚ค๋ฉด์„œ (DP์˜ ์กฐ๊ฑด) ๋งˆ์ง€๋ง‰๊นŒ์ง€ ํ–‰๋ ฌ์„ ์™„์„ฑํ•˜๊ฒŒ ๋˜๋ฉด 

์ด๋ ‡๊ฒŒ ํ–‰๋ ฌ์ด ์™„์„ฑ๋˜๊ณ  ํ–‰๋ ฌ์˜ ๋งˆ์ง€๋ง‰ ๊ฐ’์ด LCS์˜ ๊ธธ์ด ์ฆ‰ 3์ด ๋„์ถœ๋œ๋‹ค. 

 

โžฐ c++ ์ฝ”๋“œ : 

//
//  9251_LCS.cpp
//  SOMA๐Ÿ‘ฉ๐Ÿป‍๐Ÿ’ป
//
//  Created by JoSoJeong on 2021/03/01.
//

#include <cstdio>
#include <cstring>
#include <algorithm>

char X[1010];
char Y[1010];
int C[1010][1010];

using namespace std;

int main()
{
    scanf("%s", &X);
    scanf("%s", &Y);
    
    int lenX = (int)strlen(X);
    int lenY = (int)strlen(Y);
 
    for (int i = 1; i <= lenX; i++) {
        for (int j = 1; j <= lenY; j++) {
            if (X[i - 1] == Y[j - 1])
                C[i][j] = C[i - 1][j - 1] + 1;
            else
                C[i][j] = max(C[i - 1][j], C[i][j - 1]);
        }
    }
    printf("%d\n", C[lenX][lenY]);
    
    return 0;
}

 

๋Œ“๊ธ€