LCS

LCS(Longest Common Substring,Subsequence) 최장 부분 문자열

최장 부분 문자열 은 두가지 형태가 존재,

Substring은 연속적인 부분 문자열,

Subsequence는 불연속 적이어도 되는 부분 문자열

 

 Substring을 구하는 방법은 동적 계획법으로 간단하게 해결가능,

 

	String str1 = br.readLine();
        String str2 = br.readLine();
        int ans=0;
        int[][] dp = new int[str1.length()+1][str2.length()+1];
        for(int i=1; i<=str1.length(); i++){
            for(int j=1; j<=str2.length(); j++){
                if(str1.charAt(i-1)==str2.charAt(j-1)){
                    dp[i][j] = dp[i-1][j-1] + 1;
                    if(ans < dp[i][j]){
                        ans = dp[i][j];
                    }
                }
            }
        }

연속적으로 같은 문자열만 이전 연속 문자열 길이에 + 1 해줌

 

Subsequence를 구하는 방법은 각 문자열에 앞에 "0"을 추가하고 테이블을 만들어서 해결

두 문자열을 테이블로 구성하고 각 문자마다 같은지 비교,

같은 문자면, 왼쪽 대각선 길이 + 1,

다른 문자면, 왼쪽 or 위 쪽 길이 중 큰값

LCS문자열의 길이 뿐 아니라 문자열까지 구하고 싶다면,

길이를 구할때 해당 테이블 값이 대각선 + 1 인지 왼쪽 혹은 위쪽 길이 인지 체크해주고,

체크된 값을 사용해서 테이블의 가장 끝에서부터 추적해 감, 대각선 + 1 한 값이면 LCS문자열에 추가해줌

(테이블에서 가장 큰값부터 작은값으로 역추적 하는 느낌)

	String str1 = "0"+br.readLine();
        String str2 = "0"+br.readLine();
        int[][] lcs = new int[str2.length()][str1.length()];
        String[][] dir = new String[str2.length()][str1.length()];
        int len=0;

        //길이 구하기
        for(int i=1; i<str2.length(); i++){
            for(int j=1; j<str1.length(); j++){
                if(str2.charAt(i)==str1.charAt(j)){//같은 문자면 왼쬑 위 대각선 길이 + 1
                    lcs[i][j] = lcs[i-1][j-1] + 1;
                    dir[i][j] = "diagonal";
                }
                else{
                    lcs[i][j] = Math.max(lcs[i][j-1],lcs[i-1][j]); //다른 문자면 왼쪽 혹은 위 쪽 길이 중 큰값
                    if(lcs[i][j]==lcs[i][j-1]){
                        dir[i][j] = "left";
                    }
                    else{
                        dir[i][j] = "up";
                    }
                }
                if(len < lcs[i][j])
                    len = lcs[i][j];
            }
        }

        //lcs 문자열 구하기
        int i = str2.length()-1;
        int j = str1.length()-1;
        StringBuilder ans = new StringBuilder();
        while(dir[i][j] != null){
            if(dir[i][j]=="diagonal"){// 대각선 이면 lcs문자열에 추가
                ans.append(str1.charAt(j));
                i--;
                j--;
            }
            else{
                if(dir[i][j]=="left"){//왼쪽으로 이동
                    j--;
                }
                else{//위쪽으로 이동
                    i--;
                }
            }
        }
        ans.reverse().toString();

참고 사이트:

https://twinw.tistory.com/126

 

LCS(Longest Common Subsequence) 알고리즘

1. 개요 LCS란 Longest Common Subsequence의 약자로 최장 공통 부분 문자열이다. 우리가 알고 있는 substring과 비교하면 substring은 연속된 부분 문자열이고 subsequence는 연속적이지는 않은 부분 문자열이다...

twinw.tistory.com

https://mygumi.tistory.com/126

 

LCS(최장 공통 부분 수열) 알고리즘 :: 마이구미

이번 글은 LCS(Longest Common Subsequence) 알고리즘은 다뤄본다. 최장 공통 부분 수열(LCS)은 LIS 최장 증가 부분 수열과 비슷하게 생각하면 된다. LCS 또한 LIS와 같이 DP(동적 계획법)을 기반으로 한다. LCS..

mygumi.tistory.com

 

'Algorithm & Data Structure > Background' 카테고리의 다른 글

플로이드 와샬(Floyd Warshall) 알고리즘  (0) 2020.05.01
Kruskal(크루스칼) 알고리즘  (0) 2020.03.23
UnionFind 알고리즘  (0) 2020.03.23
[Java] HashSet  (0) 2020.01.07
[JAVA] 자료형 정리  (0) 2019.11.24

https://www.acmicpc.net/problem/9252

 

9252번: LCS 2

LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다. 예를 들어, ACAYKP와 CAPCAK의 LCS는 ACAK가 된다.

www.acmicpc.net

최장 부분 문자열 문제였습니다.

Substring과 달리 Subsequence는 연속적이지 않아도 됩니다.

이번 문제는 LCS문자열의 길이뿐 아니라 문자열까지 출력하는 문제입니다.

 

LCS의 길이를 구할때마다 String[][] 배열에 해당 좌표가 왼쪽 대각선 + 1 인지, 왼쪽 길이 인지, 위 쪽 길이 인지 체크해줍니다.

길이를 구한 후, 문자열을 찾아줍니다.

"diagonal"(대각선)으로 저장되어 있는 좌표면 해당 좌표의 문자를 정답 문자열에 추가해줍니다.

 

https://www.acmicpc.net/problem/5582

 

5582번: 공통 부분 문자열

문제 두 문자열이 주어졌을 때, 두 문자열에 모두 포함된 가장 긴 공통 부분 문자열을 찾는 프로그램을 작성하시오. 어떤 문자열 s의 부분 문자열 t란, s에 t가 연속으로 나타나는 것을 말한다. 예를 들어, 문자열 ABRACADABRA의 부분 문자열은 ABRA, RAC, D, ACADABRA, ABRACADABRA, 빈 문자열 등이다. 하지만, ABRC, RAA, BA, K는 부분 문자열이 아니다. 두 문자열 ABRACADABRA와 ECADADABRBCR

www.acmicpc.net

최장 공통 부분 문자열 문제입니다.

두 문장 에서 연속되는 가장 긴 부분 문자열을 찾아내는 문제입니다.

동적 계획법 으로 해결했습니다.

참고 사이트: https://mygumi.tistory.com/126

 

LCS(최장 공통 부분 수열) 알고리즘 :: 마이구미

이번 글은 LCS(Longest Common Subsequence) 알고리즘은 다뤄본다. 최장 공통 부분 수열(LCS)은 LIS 최장 증가 부분 수열과 비슷하게 생각하면 된다. LCS 또한 LIS와 같이 DP(동적 계획법)을 기반으로 한다. LCS..

mygumi.tistory.com

 

+ Recent posts