LCS

2025. 4. 23. 12:59·알고리즘(코딩테스트)
목차
  1. 1. Longest Common Substring
  2. 2. Longest Common Subsequence
  3. 3. LCS 문자열 찾기
  4. 4. 실습 코드

1. Longest Common Substring


두 문자열 사이에서 연속적으로 공통된 문자 중 가장 긴 문자열 찾기 (최장 공통 문자열)

 

과정

  • 2차원 배열을 통해서 하나씩 비교하면서
  • 두 문자가 다르면 dp[i][j] = 0
  • 같은 문자가 나온 순간 dp[i][j] = dp[i-1][j-1] + 1

아래와 같은 표의 형태로 dp 배열을 구성할 수 있다

  - A B C  D E F
- 0 0 0 0 0 0 0
G 0 0 0 0 0 0 0
B 0 0 1 0 0 0 0
C 0 0 0 2 0 0 0
D 0 0 0 0 3 0 0
F 0 0 0 0 0 0 1
E 0 0 0 0 0 1 0

 

결론적으로 최장 공통 문자열의 길이는 3이 된다.

 

 

2. Longest Common Subsequence


최장 공통 "부분수열" -> 중간에 끊기더라도 부분수열로서 연속된 문자열을 찾기

 

과정

  • 2차원 배열을 통해서 하나씩 비교하기
  • 두 문자가 다르면 dp[i - 1][j] 와 dp[i][j - 1] 중 큰 값 선택
  • 두 문자가 같으면 dp[i - 1][j - 1] + 1
  - A B C D E F
- 0 0 0 0 0 0 0
G 0 0 0 0 0 0 0
B 0 0 1 1 1 1 1
C 0 0 1 2 2 2 2
D 0 0 1 2 3 3 3
F 0 0 1 2 3 3 4
E 0 0 1 2  3 4 4

 

결론적으로 정답은 4가 된다.

 

 

3. LCS 문자열 찾기


위의 문제에서는 길이를 찾는 것에 집중하였고, 이번에는 실제로 문자열을 찾기 방법을 알아보자

 

과정

  • 위에서 구한 배열을 먼저 구한 후 배열의 가장 마지막 값에서 시작하여 dp[i - 1][j] 또는 dp[i][j - 1] 중 같은 값을 찾는다.
  • 같은 값이 있는 경우 해당 방향으로 이동
  • 같은 값이 없는 경우 dp[i - 1][j - 1] 로 이동 후 dp[i][j]의 값을 결과 문자열에 넣는다.
  • dp[i][j]의 값이 0이 되는 경우 마무리하면 된다.

아래 그림의 경우 FDCB 가 찍히기 때문에 이 문자를 뒤집어서 BCDF가 정답이 된다.

 

 

4. 실습 코드


LCS 문제

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

더보기
#include <iostream>
using namespace std;

string str1;
string str2;
int dp[1002][1002];
int answer = 0;

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> str1 >> str2;

	for (int i = 1; i <= str1.size(); ++i)
	{
		for (int j = 1; j <= str2.size(); ++j)
		{
			if (str1[i - 1] == str2[j - 1])
				dp[i][j] = dp[i - 1][j - 1] + 1;

			else
				dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);			
			answer = max(answer, dp[i][j]);
		}
	}
	cout << answer;
}

 

LCS 문자열 구하는 문제

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

더보기
#include <iostream>
#include <algorithm>
using namespace std;

string str1;
string str2;
string ans;
int dp[1002][1002];
int answer = 0;

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> str1 >> str2;

	for (int i = 1; i <= str1.size(); ++i)
	{
		for (int j = 1; j <= str2.size(); ++j)
		{
			if (str1[i - 1] == str2[j - 1])
				dp[i][j] = dp[i - 1][j - 1] + 1;

			else
				dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
			answer = max(answer, dp[i][j]);
		}
	}
	
	int x = str1.size();
	int y = str2.size();
	
	while (dp[x][y] != 0)
	{
		if (dp[x][y] == dp[x][y - 1])
			y--;
		else if (dp[x][y] == dp[x - 1][y])
			x--;
		else
		{
			ans += str1[x-1];
			x--;
			y--;
		}
	}
	reverse(ans.begin(), ans.end());
	cout << answer << "\n" << ans;
}

 

'알고리즘(코딩테스트)' 카테고리의 다른 글

알고리즘 수업 최종 정리  (0) 2025.04.28
MST  (0) 2025.04.25
DP (배낭 문제)  (0) 2025.04.11
백트래킹 2  (0) 2025.04.04
최단 경로 구하기 (다익스트라, 벨만-포드)  (0) 2025.03.25
  1. 1. Longest Common Substring
  2. 2. Longest Common Subsequence
  3. 3. LCS 문자열 찾기
  4. 4. 실습 코드
'알고리즘(코딩테스트)' 카테고리의 다른 글
  • 알고리즘 수업 최종 정리
  • MST
  • DP (배낭 문제)
  • 백트래킹 2
gbleem
gbleem
gbleem 님의 블로그 입니다.
  • gbleem
    gbleem 님의 블로그
    gbleem
  • 전체
    오늘
    어제
    • 분류 전체보기 (185)
      • Unreal Engine (73)
      • C++ (19)
      • 알고리즘(코딩테스트) (28)
      • TIL (60)
      • CS (4)
      • 툴 (1)
  • 블로그 메뉴

    • 홈
    • 카테고리
  • 링크

    • 과제용 깃허브
    • 깃허브
    • velog
  • 공지사항

  • 인기 글

  • 태그

    상속
    addonscreendebugmessage
    enhanced input system
    gamestate
    map을 vector로 복사
    매크로 지정자
    C++
    싱글턴
    motion matching
    additive animation
    템플릿
    Vector
    BFS
    cin함수
    blend pose
    actor 클래스
    applydamage
    DP
    character animation
    const
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
gbleem
LCS

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.