백준 15483번: 최소 편집

최창효·2023년 2월 2일
0
post-thumbnail
post-custom-banner

문제 설명

접근법

  • 최장 공통 부분 수열(LCS)에 대한 이해가 필요합니다. LCS를 잘 모르는 분들은 백준 17218번: 비밀번호 만들기를 먼저 풀어보는 걸 추천드립니다.

  • dp[i][j] = 문자열1의 i까지문자열2의 j까지로 만들기 위해 필요한 최소연산 입니다. 우선 단순한 예제를 직접 실행해 보겠습니다. 왼쪽 문자열에서 오른쪽 문자열을 만든다고 생각하고 풀었습니다.

    -abc
    cX1X2X3
    bX4X5X6
    aX7X8X9

    X1: ca로 바꿔야 합니다. ca교체합니다. (1)
    X2: cab로 바꿔야 합니다. ca교체하고, b추가합니다. (2)
    X3: cabc로 바꿔야 합니다. a추가하고, b추가합니다. (2)

    X4: cba로 바꿔야 합니다. 삭제b를 지우고, ca교체합니다. (2)
    X5: cbab로 바꿔야 합니다. ca교체합니다. (1)
    X6: cbabc로 바꿔야 합니다. ca교체하고, c추가합니다. (2)

    X7: cbaa로 바꿔야 합니다. 삭제c를 지우고, 삭제b를 지웁니다. (2)
    X8: cbaab로 바꿔야 합니다. ca교체하고, 뒤에 있는 a삭제합니다. (2)
    X9: cbaabc로 바꿔야 합니다. ca교체하고, 뒤에 있는 ac교체합니다. (2)

    완성된 모양은 다음과 같습니다.

    -abc
    c122
    b212
    a222
  • 중요한 건 앞의 계산이 모두 진행되었다고 가정하고 문자열1의 i번째 문자와 문자열2의 j번째 문자를 비교하는 것입니다. 편의상 문자열1의 i번째 문자를 S1_i, 문자열2의 j번째 문자를 S2_j라고 하겠습니다.

    • S1_iS2_j가 같으면 연산이 필요하지 않습니다. cbab로 바꾸는 X5에서 S1_i와 S2_j가 같았기 때문에 ca로 바꾸는 X1연산과 시행 횟수가 동일합니다.
      dp[i][j] = dp[i-1][j-1]
    • S1_iS2_j가 다르면 연산이 필요합니다. 앞의 계산이 모두 진행되었다고 가정한 채로(앞의 문자들은 모두 해당 횟수만큼 사용해 같은 문자로 변경된 상태로) 마지막 문자를 삭제 또는 추가 또는 교체하면 원하는 문자열을 만들 수 있습니다. 세 가지 방법 중 가장 연산횟수가 적은 방식을 선택하면 됩니다.
      • 삭제연산을 한다는건 dp[i][j-1] + 1과 동일합니다.
      • 추가연산을 한다는건 dp[i-1][j] + 1과 동일합니다.
      • 교체연산을 한다는건 dp[i-1][j-1] + 1과 동일합니다.

정답

import java.util.*;
import java.io.*;

public class Main {
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String s1 = br.readLine();
		String s2 = br.readLine();
		int[][] dp = new int[s1.length()+1][s2.length()+1];

		// padding
		for (int i = 0; i < dp.length; i++) {
			dp[i][0] = i;
		}
		for (int i = 0; i < dp[0].length; i++) {
			dp[0][i] = i;
		}
		
		for (int i = 1; i < s1.length()+1; i++) {
			for (int j = 1; j < s2.length()+1; j++) {
				if(s1.charAt(i-1) == s2.charAt(j-1)) {
					dp[i][j] = dp[i-1][j-1];
				}else {
					dp[i][j] = Math.min(Math.min(dp[i-1][j], dp[i][j-1]),dp[i-1][j-1])+1;					
				}
			}
		}
		
		System.out.println(dp[s1.length()][s2.length()]);

	}
}	
profile
기록하고 정리하는 걸 좋아하는 개발자.
post-custom-banner

0개의 댓글