250x250
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- proxy
- 데이터베이스
- RDBMS
- 조인
- index
- mutable
- acid
- reverse프록시
- forward프록시
- 자료구조
- 인덱스
- binarySearch
- Database
- NoSQL
- 방어적복사
- 이진탐색
- 정규화
- 불변객체
- transaction
- 깊은복사
- immutable
- 프록시서버
- java
- ERD
- 알고리즘
- 얕은복사
Archives
- Today
- Total
jacketList
백준:9251 - LCS(Longest Common Subsequence, 최장 공통 부분 수열) 본문
728x90
반응형
문제 개요
두개의 문자를 입력받는다.
입력받은 문자열을 비교하여 두 문자열의 부분 수열이 되는 수열 중 가장 긴 수열의 길이를 구해 출력해주어야 한다.
풀이 방법을 생각하지 못해 도움을 받아 풀었다.
두 문자열을 비교해주어야 하니 행과 열에 문자열을 적어주고 하나씩 비교하며 길이를 적어주었다.
1. ACAYKP 와 C 비교 -> 처음 A와 비교했을 때는 일치하는 문자가 없기 때문에 0의 값이 들어가고 이후 C는 1개가 무조건 포함되므로 1이 들어간다.
2. ACAYKP 와 CA 비교 -> 위와 마찬가지 방식으로 적어주고 문자열에 CA가 포함된 순간 값이 1개 증가한다.
.
.
.
3. ACAYKP 와 CAPCAK 비교 -> 두 문자열에서 가장 긴 수열의 길이는 ACAK로 4가 출력값이 된다.
해당 방식을 사용하여 Top-Down 방식과 Bottom-Up방식으로 코드를 구현해보자
Top-Down
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Practice {
static char[] str1;
static char[] str2;
static Integer[][] dp;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s1 = br.readLine();
String s2 = br.readLine();
str1 = s1.toCharArray(); //String 문자열을 char배열로 변환해준다.
str2 = s2.toCharArray();
dp = new Integer[str1.length][str2.length];
System.out.println(Lcs(str1.length-1, str2.length-1));
}
public static int Lcs(int x, int y){
// 인덱스의 범위가 0 보다 작은 숫자가 되는 순간을 고려해주어야 한다.
if(x < 0 || y < 0){
return 0;
}
if(dp[x][y] == null){
if(str1[x] == str2[y]){
dp[x][y] = Lcs(x-1, y-1) + 1;
} else {
dp[x][y] = Math.max(Lcs(x-1, y), Lcs(x, y-1));
}
}
return dp[x][y];
}
}
- 문자열 입력받기
- 입력받은 문자열을 한 글자씩 비교하기 위해 char배열로 변환
- dp를 실행할 배열 선언
- 재귀함수 Lcs 구현
- 재귀함수의 탈출조건은 인덱스 중 어느 하나라도 음수가 나오는 순간 종료가 되어야 하기 때문에 if 조건식을 만들어준다.
- 입력받은 인덱스의 dp배열값에 값이 없다면 2가지 조건을 실행시킨다.
- str[x] 의 문자와 str[y]의 문자가 같을때 이전 비교한 길이에 +1 을 해준다.
- 같지 않다면 이전 행의값과 이전열의 값을 비교하여 큰 값을 넣어준다.
- 결과를 return 해준다.
Bottom-UP
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
char[] str1 = br.readLine().toCharArray();
char[] str2 = br.readLine().toCharArray();
int length_1 = str1.length;
int length_2 = str2.length;
// 공집합 표현을 위해 인덱스가 한 줄씩 추가 됨
int[][] dp = new int[length_1 + 1][length_2 + 1];
// 1부터 시작 (index 0 은 공집합이므로 0의 값을 갖고있음)
for(int i = 1; i <= length_1; i++) {
for(int j = 1; j <= length_2; j++) {
// (i-1)과 (j-1) 번째 문자가 서로 같다면
if(str1[i - 1] == str2[j - 1]) {
// 대각선 위 (i-1, j-1)의 dp에 +1 한 값으로 갱신
dp[i][j] = dp[i - 1][j - 1] + 1;
}
// 같지 않다면 이전 열(i-1)과 이전 행(j-1)의 값 중 큰 것으로 갱신
else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
System.out.println(dp[length_1][length_2]);
}
}
Top-Down 방식과 점화식 자체는 크게 차이가 없다
다른점은 인덱스를 1부터 시작해준다는 점과 Bottom부터 채워가기 때문에 null값과 인덱스의 범위가 벗어날때를 체크해주지 않아도 된다는 점이다.
728x90
반응형
'알고리즘 > 백준' 카테고리의 다른 글
11399 ATM (0) | 2023.11.14 |
---|---|
1018 체스판 다시 칠하기 (0) | 2023.11.14 |
진법변환2 11005 (0) | 2023.10.25 |
진법 변환 2745번 (1) | 2023.10.24 |
10809 알파벳 찾기 (0) | 2023.09.28 |