안녕하세요. 회사와 함께 성장하고 싶은 KOSE입니다.
이번 포스팅은 백준 Java vs C++ 자바 풀이를 진행하도록 하겠습니다.
문제출처:https://www.acmicpc.net/problem/3613
1. 풀이 소스
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
String str = br.readLine();
// 시작이 대문자이거나 _, 마지막이 _ 불가
if (str.charAt(0) <= '_' || str.charAt(str.length() - 1) == '_') {
System.out.println("Error!");
return;
}
// __ 불가 _A 불가 A_불가
boolean upperCase = false; // 만약 대문자가 있다면 c++로만 바꿀 수 있음
boolean toJava = false; // false라면 c++, true라면 자바로 바꾸기
char pre = str.charAt(0); // 이전 문자 파악
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (ch <= 'Z') {
if (toJava) { // _A로 끝나면 안되므로 _ 나왔는지 판단 (toJava라면 _이 나옴)
System.out.println("Error!");
return;
}
upperCase = true; // 대문자 true 설정
}
if (ch == '_') { // 만약 _가 있는데 대문자가 섞여 있다면 불가
if (upperCase || pre == '_') {
System.out.println("Error!");
return;
}
toJava = true;
}
pre = ch;
}
if (toJava) { // 자바로 바꿔야 함
boolean nextUpper = false; // 다음이 대문자가 나와야함
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (nextUpper) {
sb.append(String.valueOf(ch).toUpperCase()); // 문자열 대문자로 변경
nextUpper = false; // 초기화
} else {
if (str.charAt(i) == '_') nextUpper = true; // 다음 문자열 대문자로 설정
else sb.append(ch);
}
}
}
else { // c++로 바꿔야 함
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (ch <= 'Z') { // 만약 대문자라면
sb.append("_"); // "_소문자"로 바꾸기
sb.append(String.valueOf(ch).toLowerCase());
} else sb.append(ch);
}
}
System.out.println(sb);
}
}
2. 풀이 중점 사항
해당 문제는 반례를 생각해 내는 것이 중요한 문제였습니다.
안 되는 경우
- _ 로 시작 ex) "_a"
- 대문자로 시작 ex) "Ab"
- _로 끝남 ex) "ab_"
- 대문자와 _이 같이 쓰임 ex) "aB_b"
- __이 두 개 이상이 연속으로 쓰임 ex) "a__b"
// 시작이 대문자이거나 _, 마지막이 _ 불가
if (str.charAt(0) <= '_' || str.charAt(str.length() - 1) == '_') {
System.out.println("Error!");
return;
}
시작이 대문자이거나 "_"인 경우, 마지막 문자열이 "_"로 끝나는 경우는 처음에 확인이 가능합니다.
// __ 불가 _A 불가 A_불가
boolean upperCase = false; // 만약 대문자가 있다면 c++로만 바꿀 수 있음
boolean toJava = false; // false라면 c++, true라면 자바로 바꾸기
char pre = str.charAt(0); // 이전 문자 파악
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (ch <= 'Z') {
if (toJava) { // _A로 끝나면 안되므로 _ 나왔는지 판단 (toJava라면 _이 나옴)
System.out.println("Error!");
return;
}
upperCase = true; // 대문자 true 설정
}
if (ch == '_') { // 만약 _가 있는데 대문자가 섞여 있다면 불가
if (upperCase || pre == '_') {
System.out.println("Error!");
return;
}
toJava = true;
}
pre = ch;
}
모든 문자가 전부 소문자와 대문자로만 이루어져 있다면, 이는 Java의 변수명 형태로 작성된 것입니다.
따라서, c++로 변경 가능합니다.
반면, 모든 문자가 소문자와 "_"로만 쓰인 경우는 Java로 변경이 가능합니다.
이와 같이 O(n)으로 탐색하며 어떠한 문자로 변경 가능한지 판단합니다.
if (toJava) { // 자바로 바꿔야 함
boolean nextUpper = false; // 다음이 대문자가 나와야함
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (nextUpper) {
sb.append(String.valueOf(ch).toUpperCase()); // 문자열 대문자로 변경
nextUpper = false; // 초기화
} else {
if (str.charAt(i) == '_') nextUpper = true; // 다음 문자열 대문자로 설정
else sb.append(ch);
}
}
}
else { // c++로 바꿔야 함
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (ch <= 'Z') { // 만약 대문자라면
sb.append("_"); // "_소문자"로 바꾸기
sb.append(String.valueOf(ch).toLowerCase());
} else sb.append(ch);
}
}
이후 다시 O(n)으로 바꿔야 하는 방향으로 문자를 바꿀 수 있습니다.
자세한 풀이는 주석으로 작성하였습니다.
이상으로 Java vs C++ 자바 풀이를 마치도록 하겠습니다.
감사합니다.!
'Algorithm' 카테고리의 다른 글
[Algorithm] 백준 DP 문제 - 암호코드(2011) 자바 풀이 (0) | 2023.05.17 |
---|---|
[Algorithm] 백준 문자열 문제 - 동물원(1309) 자바 풀이 (0) | 2023.05.17 |
[Algorithm] 백준 문자열 문제 - 크로아티아 알파벳(2941) 자바 풀이 (0) | 2023.05.17 |
[Algorithm] 백준 문자열 문제 - 문자열 게임 2(20437) 자바 풀이 (2) | 2023.05.17 |
[Algorithm] 백준 문자열 문제 - 회문(17609) 자바 풀이 (0) | 2023.05.16 |