https://www.acmicpc.net/problem/3613
변수명을 받아서 C++형식의 변수면 Java형식으로, Java형식의 변수면 C++형식으로 바꿔서 출력하는 문제.
만만히 보이는 문제지만, 예외처리할게 너무 많은 문제. 남이 알려주지 않으면 예외 찾는데 엄청나게 많은 시간을 쏟을 것이다. 필자도 결국 백준 질문검색으로 들어가 무엇을 예외처리해야 하는지 알아보고 처리했다.
정리해보면 5가지의 예외가 있다.
- 1. 첫 문자가 '_' 이거나 대문자인 경우 -> C++과 Java모두 변수명의 첫글자는 무조건 소문자이기 때문에 Error! 출력
- 2. '_'와 대문자가 혼재되어 있는 경우 -> C++도 아니고 Java도 아니기 때문에 Error! 출력
- 3. 마지막 글자가 '_'인 경우 -> _는 C++에서 단어를 구분하는 용도기 때문에 맨 마지막에 오면 안되므로 Error! 출력
- 4. 변수명이 한단어로 이루어진 경우, 즉 오직 소문자로만 이루어진 변수인 경우 -> C++일 수도 있고, Java일수도 있지만, 어쨌든 한단어로 이루어져있기 때문에, 이때는 입력받은 그대로 출력한다.
- 5. '_'가 연속으로 나오는 경우 -> 알아차리기 너무 힘든 예외, 아무래도 단어를 구분하는데 '_'를 한번 쓰기 때문인듯하다. Error! 출력
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
// java의 변수인지 판단하는 함수. 대문자가 있으면 true로 간주한다.
bool isJava(const string& str) {
for (const auto& x : str)
if (isupper(x)) return true;
return false;
}
// C++의 변수인지 판단하는 함수. '_'가 있으면 true로 간주한다.
bool isCpp(const string& str) {
for (const auto& x : str)
if (x == '_') return true;
return false;
}
// 위 두 함수로 잡지 못하는 모든 예외를 처리한다.
bool isError(const string& str) {
// '_'와 대문자가 혼재되있는지 판단한다.
bool underbar = false;
bool upper = false;
for (const auto& x : str) {
if (x == '_') underbar = true;
else if (isupper(x)) upper = true;
}
if (underbar && upper) return true; // 여기서 return이 발생한다는 것은 대문자와 '_'가 모두 있다는 뜻.
// 첫 문자가 대문자거나 '_'인지 판단한다.
else if (isupper(str[0]) || str[0] == '_') return true;
// 마지막 문자가 '_'인지 판단한다.
else if (*(str.end() - 1) == '_') return true;
// '_'이 연속해서 나오는지 판단한다.
for (int i = 0; i < str.length() - 1; ++i)
if (str[i] == '_' && str[i + 1] == '_') return true;
// 이 모든 경우를 통과했다면 Error가 아니다.
return false;
}
// Java형식의 변수를 C++형식으로 바꾼다.
string JtoC(const string& var) {
string str = "";
for (const auto& x : var) {
if (isupper(x)) { // 대문자인 경우
str += '_'; // '_'를 붙이고
str += tolower(x); // 소문자로 바꿔서 붙인다.
}
else str += x; // 소문자라면 그냥 붙인다.
}
return str;
}
string CtoJ(const string& var) {
string str = "";
bool changeFlag = false; // 대문자로 바꿔야 하는지 판단할 변수
for (const auto& x : var) {
if (x == '_') changeFlag = true; // '_'인 경우, 붙이지 않고 다음 문자를 대문자로 붙인다.
else {
if (changeFlag) { // 대문자로 바꿔야 한다면
str += toupper(x); // 대문자로 바꿔서 붙이고
changeFlag = false; // 다음 문자는 소문자로 바꿔쓴다.
}
else str += x; // 바꿀 필요가 없으면 그냥 소문자로 붙인다
}
}
return str;
}
int main () {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
string varName;
cin >> varName;
if (isError(varName))
cout << "Error!";
else if (isCpp(varName))
cout << CtoJ(varName);
else if (isJava(varName))
cout << JtoC(varName);
else cout << varName;
}
'coding_test > BAEKJOON' 카테고리의 다른 글
백준 10816번 C++ 풀이 (0) | 2022.01.05 |
---|---|
백준 10815번 C++ 풀이 (0) | 2022.01.05 |
백준 9417번 C++ 풀이 (0) | 2022.01.04 |
백준 8595번 C++ 풀이 (0) | 2022.01.04 |
백준 9093번 C++ 풀이 (0) | 2022.01.02 |