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
- 연결 리스트
- 코테공부
- 알고리즘
- #코드트리 #코딩테스트 #코테공부 #백트래킹 #알고리즘 기초
- 코드트리
- 코딩테스트사이트추천
- 자바스크립트
- 웹
- 1일1코테
- C
- 자료구조
- 프로그래머스
- 코딩테스트
- Java
- 99클럽
- 자바
- 인접 행렬
- 오블완
- 갭체크
- 플로이드-워셜
- 개발자취업
- til
- 프로그래밍 언어
- 코딩테스트준비
- 항해99
- 파이썬
- 운영체제
- 데이터베이스
- 개발자루틴
- 티스토리챌린지
Archives
- Today
- Total
와드의 블로그
3613번: Java vs C++ 본문
문제
C++에서는 변수명을 작성할 때 단어와 단어 사이를 밑줄('_')로 구분하는 형식을 사용합니다. (예: c_identifier) 반면 Java에서는 첫 단어를 제외한 나머지 단어의 첫 글자를 대문자로 쓰는 형식을 사용합니다. (예: javaIdentifier) 어떤 변수명이 주어졌을 때, 이것이 C++ 형식이라면 Java 형식으로, Java 형식이라면 C++ 형식으로 변환하는 프로그램을 작성하는 문제입니다. 두 형식에 모두 맞지 않는 에러 상황이라면 "Error!"를 출력해야 합니다.
- 입력: 첫째 줄에 변수명이 주어집니다. 영문 알파벳과 밑줄('_')로만 이루어져 있으며, 길이는 100을 넘지 않습니다.
- 출력: 변환된 변수명을 출력합니다. 에러 형식인 경우 "Error!"를 출력합니다.
링크: https://www.acmicpc.net/problem/3613
풀이 1: 플래그(Flag) 변수와 replaceAll을 활용한 일괄 치환
입력된 문자열을 한 글자씩 검사하여 어떤 언어의 형식인지 플래그 변수로 판별한 뒤, 26번의 반복문과 replaceAll 메서드를 활용하여 알파벳 치환을 일괄적으로 수행하는 풀이입니다.
- 형식 판별 (Flag 확인): 문자열을 순회하며 밑줄(_)이 등장하면 isC를 true로, 대문자(A~Z)가 등장하면 isJava를 true로 설정합니다.
- 에러 검출:
- isC와 isJava가 모두 true인 경우: 밑줄과 대문자가 혼용된 형태
- s.charAt(0) >= 'A' && s.charAt(0) <= 'Z': Java 형식은 소문자로 시작해야 함
- s.startsWith("_") || s.endsWith("_"): 밑줄로 시작하거나 끝나는 경우
- s.contains("__"): 밑줄이 연속으로 등장하는 경우
- 변환 진행: 에러가 아니라면, replaceAll을 26번 순회하며 _a를 A로 바꾸거나(C++ -> Java), A를 _a로 바꾸는(Java -> C++) 치환 작업을 일괄 수행합니다.
코드 1
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String s = br.readLine();
boolean isJava = false;
boolean isC = false;
for (char c : s.toCharArray()) {
if (c == '_') {
isC = true;
} else if (c >= 'A' && c <= 'Z') {
isJava = true;
}
}
// 모든 예외 케이스 완벽 처리
if ((isC && isJava) || (s.charAt(0) >= 'A' && s.charAt(0) <= 'Z') || s.startsWith("_") || s.endsWith("_")
|| s.contains("__")) {
bw.write("Error!");
bw.flush();
return;
}
// C++ -> Java 변환
if (isC) {
for (int i = 0; i < 26; i++) {
s = s.replaceAll("_" + (char)(i + 'a'), Character.toString((char)(i + 'A')));
}
}
// Java -> C++ 변환
else {
for (int i = 0; i < 26; i++) {
s = s.replaceAll(Character.toString((char)(i + 'A')), "_" + (char)(i + 'a'));
}
}
bw.write(s);
bw.flush();
}
}
풀이 2: StringBuilder를 활용한 파싱
replaceAll은 호출될 때마다 내부적으로 새로운 String 객체를 생성하므로 메모리와 시간 측면에서 다소 비효율적일 수 있습니다. 이를 보완하기 위해 문자열을 한 번만 순회하며 O(N) 시간에 StringBuilder로 변환된 문자를 덧붙이는 정석적인 구현 방식입니다.
- 에러 검출: 풀이 1과 동일하게 까다로운 예외 상황들을 먼저 걸러냅니다.
- C++ 형식을 Java 형식으로 변환: 문자열을 순회하며 밑줄(_)을 만나면 바로 추가하지 않고, nextUpper 플래그를 true로 둡니다. 그 다음 문자가 들어올 때 대문자로 변환(Character.toUpperCase)하여 StringBuilder에 추가합니다.
- Java 형식을 C++ 형식으로 변환: 순회 중 대문자를 만나면 먼저 밑줄(_)을 추가하고, 해당 문자를 소문자로 변환(Character.toLowerCase)하여 추가합니다. 일반 소문자는 그대로 덧붙입니다.
코드 2
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String s = br.readLine();
boolean isJava = false;
boolean isC = false;
for (char c : s.toCharArray()) {
if (c == '_') {
isC = true;
} else if (c >= 'A' && c <= 'Z') {
isJava = true;
}
}
if ((isC && isJava) || (s.charAt(0) >= 'A' && s.charAt(0) <= 'Z') || s.startsWith("_") || s.endsWith("_")
|| s.contains("__")) {
bw.write("Error!");
bw.flush();
return;
}
StringBuilder sb = new StringBuilder();
// C++ -> Java 변환
if (isC) {
boolean nextUpper = false;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '_') {
nextUpper = true;
} else {
if (nextUpper) {
sb.append(Character.toUpperCase(c));
nextUpper = false;
} else {
sb.append(c);
}
}
}
}
// Java -> C++ 변환
else {
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c >= 'A' && c <= 'Z') {
sb.append('_');
sb.append(Character.toLowerCase(c));
} else {
sb.append(c);
}
}
}
bw.write(sb.toString());
bw.flush();
}
}
알고리즘 분류
구현 (Implementation), 문자열 (String)
'PS > B.O.J' 카테고리의 다른 글
| 2999번: 비밀 이메일 (0) | 2026.04.10 |
|---|---|
| 1969번: DNA (0) | 2026.04.10 |
| 2941번: 크로아티아 알파벳 (0) | 2026.04.10 |
| 1929번: 소수 구하기 (0) | 2026.04.08 |
| 단어 나누기 (0) | 2026.04.07 |