백준 - 3613번(Java vs C++)

최지홍·2022년 5월 29일
0

백준

목록 보기
135/145

문제 출처: https://www.acmicpc.net/problem/3613


문제

  • Java 예찬론자 김동규와 C++ 옹호가 김동혁은 서로 어떤 프로그래밍 언어가 최고인지 몇 시간동안 토론을 하곤 했다. 동규는 Java가 명확하고 에러가 적은 프로그램을 만든다고 주장했고, 동혁이는 Java는 프로그램이 느리고, 긴 소스 코드를 갖는 점과 제네릭 배열의 인스턴스화의 무능력을 비웃었다.

  • 또, 김동규와 김동혁은 변수 이름을 짓는 방식도 서로 달랐다. Java에서는 변수의 이름이 여러 단어로 이루어져있을 때, 다음과 같은 방법으로 변수명을 짓는다.

  • 첫 단어는 소문자로 쓰고, 다음 단어부터는 첫 문자만 대문자로 쓴다. 또, 모든 단어는 붙여쓴다. 따라서 Java의 변수명은 javaIdentifier, longAndMnemonicIdentifier, name, bAEKJOON과 같은 형태이다.

  • 반면에 C++에서는 변수명에 소문자만 사용한다. 단어와 단어를 구분하기 위해서 밑줄('_')을 이용한다. C++ 변수명은 c_identifier, long_and_mnemonic_identifier, name, b_a_e_k_j_o_o_n과 같은 형태이다.

  • 이 둘의 싸움을 부질없다고 느낀 재원이는 C++형식의 변수명을 Java형식의 변수명으로, 또는 그 반대로 바꿔주는 프로그램을 만들려고 한다. 각 언어의 변수명 형식의 위의 설명을 따라야 한다.

  • 재원이의 프로그램은 가장 먼저 변수명을 입력으로 받은 뒤, 이 변수명이 어떤 언어 형식인지를 알아내야 한다. 그 다음, C++형식이라면 Java형식으로, Java형식이라면 C++형식으로 바꾸면 된다. 만약 C++형식과 Java형식 둘 다 아니라면, 에러를 발생시킨다. 변수명을 변환할 때, 단어의 순서는 유지되어야 한다.

  • 재원이는 프로그램을 만들려고 했으나, 너무 귀찮은 나머지 이를 문제를 읽는 사람의 몫으로 맡겨놨다.

  • 재원이가 만들려고 한 프로그램을 대신 만들어보자.


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    public static void main(String[] args) throws IOException {
        StringBuilder sb = new StringBuilder();
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        String target = reader.readLine();

        // 조건 따지기
        // C++ 인가?

        if (target.matches(".*_.*")) {
            // 언더바가 있다. -> C++이다. -> Java로 바꾼다.
            if (target.matches(".*[A-Z].*")) {
                // 대문자가 있는 경우
                sb.setLength(0);
                sb.append("Error!");
            } else {
                for (int i = 0; i < target.length(); i++) {
                    if (target.charAt(i) == '_') {
                        if (i == 0 || i == target.length() - 1) {
                            sb.setLength(0);
                            sb.append("Error!");
                            break;
                        } else if (target.charAt(i + 1) == '_') {
                            sb.setLength(0);
                            sb.append("Error!");
                            break;
                        } else {
                            sb.append((char) (target.charAt(i + 1) + ('A' - 'a')));
                            i++;
                        }
                    } else {
                        sb.append(target.charAt(i));
                    }
                }
            }
        } else {
            // 언더바가 없다. -> Java이다. -> C++로 바꾼다.
            for (int i = 0; i < target.length(); i++) {
                if (target.charAt(i) >= 'A' && target.charAt(i) <= 'Z') {
                    if (i == 0) {
                        sb.setLength(0);
                        sb.append("Error!");
                        break;
                    } else {
                        sb.append("_");
                        sb.append((char) (target.charAt(i) - ('A' - 'a')));
                    }
                } else {
                    sb.append(target.charAt(i));
                }
            }
        }

        System.out.println(sb);
    }

}

  • 예외 처리를 잘못하여 생각보다 시간이 걸렸다. 결국 질문에 나오는 예외들을 모아서 해결할 수 있었다.
  • 처음에 언더바가 오거나 끝에 언더바가 오는 경우, 언더바가 연속되는 경우, 처음에 대문자가 오는 경우는 처음에 떠올려서 예외 처리 하였다.
  • 그러나 언더바가 오는데 대문자가 오는 경우(C++로 처리했는데 대문자가 있는 경우)를 처리하지 못했다.
  • C++을 처리하는 로직에서 언더바를 만날 경우 그 다음에 오는 값을 대문자로 바꾸는데 이 값이 대문자인지, 소문자인치 체크하는 과정없이 수를 더해서 이상한 값이 나왔다.
  • 처음에 정규표현을 통해 C++에서 대문자를 찾는 방식으로 해결할 수 있었다.
profile
백엔드 개발자가 되자!

0개의 댓글