LCS (Longest Common Sequence)

공통 최장 수열, LCS, Longest Common Sequence 라고도 부름

문제 내용

문자열이 하나 주어지고, 그 문자열을 "JENNIFERSOFT" 로 바꿀때 최소 연산 횟수를 출력하라

문제 해결 방법 : 위 문제 풀다가 코드를 올림, LCS 로 공통 최장 수열을 찾고, 공통되지 않은 부분에서의 추가, 삭제의 최대 값을 더하면 답이 나옴

아래의 코드는 다음의 내용이 있음

  • LCS 를 통해 공통 최장 수열의 길이를 얻을 수 있다
  • path 를 기록해서 공통되거나 추가, 삭제된 부분에 대한 정보를 얻을 수 있다

이 정도면 많이 썼음, 나의 시간은 소중하니까!

훗날 신입이 정리해줄거라 믿고있음

코드

#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace std;

int dy[1002][1002], path[1002][1002];

int lcs(char *a, char *b, int alen, int blen)
{
    int i, j;

    for ( i = 1; i <= alen; i++ )
        for ( j = 1; j <= blen; j++ ) {
            if ( dy[i-1][j] > dy[i][j-1] ) {
                dy[i][j] = dy[i-1][j];
                path[i][j] = 1;
            } else {
                dy[i][j] = dy[i][j-1];
                path[i][j] = 2;
            }

            if ( a[i] == b[j] && dy[i][j] < dy[i-1][j-1] + 1 ) {
                dy[i][j] = dy[i-1][j-1] + 1;
                path[i][j] = 0;
            }
        }

    return dy[alen][blen];
}

int solve(char *a, char *b)
{
    int alen = strlen(a+1), blen = strlen(b+1);
    int i = alen, j = blen, ans = 0, adiff=0, bdiff=0;

    lcs(a, b, alen, blen);

    while ( i > 0 && j > 0 ) {
        switch(path[i][j]) {
            case 0:
                ans += max(adiff, bdiff);
                i--, j--, adiff=0, bdiff=0;
                break;
            case 1:
                i--;
                adiff++;
                break;
            case 2:
                j--;
                bdiff++;
                break;
        }
    }
    while ( i > 0 )
        i--, adiff++;
    while ( j > 0 )
        j--, bdiff++;

    ans += max(adiff, bdiff);
    return ans;
}

int main()
{
    char a[1002], b[1002];

    strcpy(a+1, "JENNIFERSOFT");
    scanf("%s", b+1);
    printf("%d", solve(a, b));

    return 0;
}

정리

신입 님들이 정리해주십쇼

참고자료

신입 님들이 정리해주십쇼

관련문제

신입 님들이 정리해주십쇼

results matching ""

    No results matching ""