https://www.acmicpc.net/problem/1958
1958번: LCS 3
첫 줄에는 첫 번째 문자열이, 둘째 줄에는 두 번째 문자열이, 셋째 줄에는 세 번째 문자열이 주어진다. 각 문자열은 알파벳 소문자로 이루어져 있고, 길이는 100보다 작거나 같다.
www.acmicpc.net
계속 이어서 LCS의 세 번째 문제입니다.
LCS를 충분히 이해했다면 쉽게 접근이 가능합니다.
최소공배수처럼 접근해서 두 문자열의 LCS를 먼저 구하고, 구한 문자열과 비교하면 구현이... 틀립니다!
예외가 존재하기 때문인데, 쉽게 생각해 낼 수 있는 예외는
처음 구한 LCS와 길이가 같은 다른 문자열이 존재하는 경우도 있을 것 같고, 3개 문자열의 LCS가 두 문자열의 LCS와 다른 문자를 갖는 경우도 있을 것 같네요.
AAAAAAAD
ADAAAAA
AD
3개의 문자열이 있을 때 세 문자열의 LCS는 AD가 되겠지만 1번과 2번 문자열의 LCS는 AAAAAA가 되어 두 문자열의 LCS를 먼저 구할 경우 오답이 나오게 됩니다.
그럼 어떻게 구현해야할까요?
LCS를 구하던 방법과 똑같이 하되, 문자열이 세 개가 되었으니 3차원 배열로 확장해서 구현하면 됩니다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
char[] str1 = br.readLine().toCharArray();
int l1 = str1.length;
char[] str2 = br.readLine().toCharArray();
int l2 = str2.length;
char[] str3 = br.readLine().toCharArray();
int l3 = str3.length;
int[][][] dp = new int[l3 + 1][l2 + 1][l1 + 1];
for (int i = 1; i <= l3; i++) {
char c3 = str3[i - 1];
for (int j = 1; j <= l2; j++) {
char c2 = str2[j - 1];
for (int k = 1; k <= l1; k++) {
if (c3 == c2 && c2 == str1[k - 1]) {
dp[i][j][k] = dp[i - 1][j - 1][k - 1] + 1;
} else {
dp[i][j][k] = Math.max(dp[i][j][k - 1], Math.max(dp[i - 1][j][k], dp[i][j - 1][k]));
}
}
}
}
System.out.println(dp[l3][l2][l1]);
}
}
바로 이렇게요.
감사합니다!
(String의 순서를 거꾸로 비교한 건 LCS 1번, 2번에서 사용한 코드를 수정해서 작성했기 때문입니다! index만 맞는다면 어떤 식으로 반복문을 작성해도 상관없습니다.)
728x90
'🔍 알고리즘 > 백준 Java' 카테고리의 다른 글
[JAVA] 백준 4600번. 정글의법칙 (실버2) (0) | 2021.11.30 |
---|---|
[JAVA] 백준 2565번. 전깃줄 (실버1) (0) | 2021.11.30 |
[JAVA] 백준 9252번. LCS 2 (골드5) (0) | 2021.11.28 |
[JAVA] 백준 9251번. LCS (골드5) (0) | 2021.11.28 |
[Java] 백준 1000번. A+B (브론즈5) (0) | 2021.11.26 |