[JAVA] 백준 15904번. UCPC는 무엇의 약자일까?

정연희·2022년 1월 19일
0

알고리즘 풀이

목록 보기
2/21

문제

한 문자열이 주어졌을 때, 그 문자열이 UCPC로 줄어질 수 있는 것인지 확인하는 문제이다.
즉, 1) 그 문자열에 U, C, P, C라는 char가 있고, 2) 그 문자들이 문자열에 위치한 index가 오름차순인지, 이 두 조건을 만족시키는지 판별하면 된다.
-> 이때, 소문자와 대문자를 구별한다는 점을 주의해야 한다. 가령, "University Computer Programming Contest"은 "UCPC"로 축약 가능하지만, "University Computer programming Contest"는 축약이 불가능하다.

입력

한 줄에 알파벳 대소문자, 공백으로 구성된 문자열이 주어진다.
(문자열의 길이는 최대 1,000자이다. 문자열의 맨 앞과 맨 끝에 공백이 있는 경우는 없고, 공백이 연속해서 2번 이상 주어지는 경우도 없다.)

출력

첫 번째 줄에 입력으로 주어진 문자열을 적절히 축약해 "UCPC"로 만들 수 있으면 "I love UCPC"를 출력하고, 만들 수 없으면 "I hate UCPC"를 출력한다.

문제풀이

이 문제를 풀 수 있는 방법은 다양하겠지만, 문자열 조작하는 것이 포인트인 만큼 StringBuffer/StringBuilder를 사용하여 풀면 편리하다.

Java에서는 문자열을 다룰 때 주로 String을 사용하게 되지만, String은 문자열 자체를 변경하는 것은 불가능하다. 그래서 String을 조작하게 되면 새로운 문자열과 그 문자열에 해당되는 새로운 주소 값이 생성되어 할당된다. 즉, String을 조작할수록 메모리가 쌓이게 된다는 것이다. 그렇기에 문자열 조작을 많이 하게 될 경우, 새로운 문자열을 생성하는 방식이 아닌 문자열 자체를 변경하는 StringBuffer/StringBuilder를 사용하는 것이 좋다.

이에 따라 아래 코드에서는 StringBuffer를 사용하여 풀었다. 위 문제 설명에서 언급했듯이, 문자열이 UCPC로 축약가능한 경우는 1) 그 문자열에 U, C, P, C라는 char가 있고, 2) 그 문자들이 문자열에 위치한 index가 오름차순인지, 이 두 조건을 만족시킨다. 그래서 각 문자씩 indexOf()와 delete()를 이용해 1번 조건을 만족시키는지 확인했다. indexOf()는 찾는 문자가 존재하면 양수를, 존재하지 않는다면 음수를 반환하는 함수인데, delete()을 이용하여 존재하지 않는 경우에서는 StringIndexOutOfBoundsException e 에러를 발생하도록 하고, try-catch문이 이를 캐치하여 실패한 경우로 간주하도록 했다. 2번 조건을 만족시키기 위해서 delete()에 시작 index를 오름차순으로 설정해놓았다.

이때, 마지막 문자인 'C'만 예외적으로 lastIndexOf()를 사용해야 한다. indexOf()을 사용할 경우, 원래 문자열에서 'C'가 처음 발견되는 index를 반환하는데, 'C'가 두개 있더라도 첫 'C'의 index를 반환한다. 즉, UCPC로 축약가능한 경우에도 indexOf()는 UCPC의 두번째 문자인 'C'의 index를 반환한다는 것이다. 그렇기에 lastIndexOf()를 사용해야 한다!

StringBuffer와 StringBuilder의 차이
문자열 조작하는 method들은 StringBuffer든 StringBuilder든 동일하다. 유일한 차이점은 실행가능한 thread 개수이다. StringBuilder는 single thread만 지원 가능하다. 반면에
StringBuffer는 여러 개의 thread를 수행할 수 있으며, method들이 순서대로 실행될 수 있도록 동기화된다. 이 클래스는 동기화를 수행하기 때문에 thread가 한 개일 경우 동기화를 수행하지 않음으로써 더 빠른 StringBuilder를 사용하는 것이 더 좋다.
https://docs.oracle.com/javase/7/docs/api/java/lang/StringBuffer.html

코드

import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
    	//input&data structure
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        StringBuffer line = new StringBuffer();
        line.append(in.readLine());
        
        //축약
        try{
            line.delete(0, line.indexOf("U"));
            line.delete(1, line.indexOf("C"));
            line.delete(2, line.indexOf("P"));
            line.delete(3, line.lastIndexOf("C"));
        } catch(StringIndexOutOfBoundsException e){ 	//축약 불가능한 경우: 문자 존재하지 않거나, U, C, P, C 인덱스가 오름차순이지 않은 경우
            System.out.println("I hate UCPC");
            System.exit(0);	//finally 블록으로 넘어가지 않도록 프로그램 실행을 멈춘다.
        } finally {		//축약 가능한 경우
            System.out.println("I love UCPC");
        }
    }
}

어려웠던 점, 배운 점

  • StringBuffer와 StringBuilder에 대해 알아볼 수 있어 ㅆ따.
  • 'C'가 두 개이기 때문에 두 번째 'C'에는 lastIndexOf()를 사용해야 하지만, 처음에는 indexOf()을 사용하여 에러가 났었다. 다음부터는 문제 조건을 더움 꼼꼼히 분석해야겠다..!

0개의 댓글