📌 문제
📌 풀이 개요
이 문제의 핵심은 Java 형식(Camel case)과 Cpp 형식(Snake case)의 특징을 확인하여 이를 서로 변환하는 것이다.
- 각 형식의 예외 조건을 찾아 해당 형식에 부합한지를 판별해야 한다.
- 변수명의 이름이 바뀔 때마다 Java 형식은 대문자가 되고, Cpp 형식은 밑줄('_')이 따라 붙는다.
- 여기에 맞지 않는 것은 예외 처리로 판별한다.
📌 풀이
1. Java 형식이 아닐 때
- 첫글자가 대문자일 경우
- 밑줄이 하나라도 있을 경우
2. Cpp 형식이 아닐 때
- 양끝에 밑줄이 있을 경우
- 밑줄이 2개 이상 붙어 있을 경우
- 대문자가 하나라도 있을 경우
이제 위의 형식을 판별했다면 서로 다른 형식으로 변환하면 된다.
3. Cpp에서 Java로 변환할 때: 밑줄 다음의 단어를 대문자로 바꾸고 밑줄 지우기
- '다음 인덱스'를 고려하면 인덱스 범위를 초과하는 에러가 날 수 있다.
- 이를 방지하기 위하여 대문자를 알려주는 변수 flag를 이용했다.
4. Java에서 Cpp로 변환할 때: 대문자 앞에 밑줄을 넣고 대문자를 소문자로 바꾸기
- 인덱스 중간에 밑줄을 삽입해야 하기에 추가할 때마다 인덱스가 하나씩 추가된다.
- 새 인덱스를 매번 고려하기에 더해야 할 인덱스 변수 j를 이용했다.
📌 코드
import Foundation
// 대문자 소문자를 각각 문자열로 상수에 할당
let upperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
let lowerCase = "abcdefghijklmnopqrstuvwxyz"
// 대문자가 맞는지 검사하는 함수 정의
func isUpperCase(_ letter: Character) -> Bool {
for capital in upperCase {
if (letter == capital) {
return true
}
}
return false
}
// 대문자가 맞는지 검사하는 함수 정의
func isLowerCase(_ letter: Character) -> Bool {
for small in lowerCase {
if (letter == small) {
return true
}
}
return false
}
// Java 형식인지 검사하는 함수 정의
func isJavaFormat(_ str: String) -> Bool {
// Java 형식에서 첫글자가 대문자일 경우 거짓
if (isUpperCase(str[str.startIndex])) {
return false
}
// 하이픈이 하나라도 있을 경우 거짓
for char in str {
if (char == "_") {
return false
}
}
// 나머지 경우 참
return true
}
// Cpp 형식인지 검사하는 함수 정의
func isCppFormat(_ str: String) -> Bool {
// 첫 인덱스나 마지막 인덱스에 하이픈이 있는 경우 거짓
if (str[str.startIndex] == "_" || str[str.index(before: str.endIndex)] == "_") {
return false
}
// 연속된 하이픈이 있는 경우 거짓
if (str.contains("__")) {
return false
}
// Cpp 형식은 대문자가 하나라도 있으면 거짓
for char in str {
if (isUpperCase(char)) {
return false
}
}
// 나머지 경우 참
return true
}
// Cpp 형식을 Java 형식으로 바꾸는 함수 정의
func convertCppToJava(_ str: String) -> String {
var arr: [Character] = Array(str)
let range = arr.count
var flag = 0
var result = String()
for i in 0..<range {
if (arr[i] == "_" && flag == 0) {
flag += 1
continue
}
else if (flag == 1) {
arr[i] = Character(arr[i].uppercased())
flag = 0
}
}
result = String(arr).components(separatedBy: ["_"]).joined()
return result
}
// Java 형식을 Cpp 형식으로 바꾸는 함수 정의
func convertJavaToCpp(_ str: String) -> String {
var arr: [Character] = Array(str)
let range = arr.count
var result = String()
var j = 0
for i in 0..<range {
// insert 때문에 이후에 'i'가 아닌 'i + j' 인덱스에 접근
if (isUpperCase(arr[i + j])) {
arr[i + j] = Character(arr[i + j].lowercased())
arr.insert("_", at: i + j)
j += 1 // 요소 삽입 후 j 증가
}
}
result = String(arr)
return result
}
// 주어진 입력을 input에 문자열로 할당
var input = readLine()!
// 결괏값을 빈 문자열로 할당
var result = String()
// Cpp 형식일 경우 Java 형식으로 변형하여 결괏값에 할당
if (isCppFormat(input)) {
result = convertCppToJava(input)
}
// Java 형식일 경우 Cpp 형식으로 변형하여 결괏값에 할당
else if (isJavaFormat(input)) {
result = convertJavaToCpp(input)
}
// 둘 다 아니면 "Error!"를 결괏값에 할당
else {
result = "Error!"
}
// 결괏값 출력
print(result)
📌 풀이
isUppercase/isLowercase 프로퍼티를 활용할 줄 몰라서 함수를 직접 만들었다.... 아이러니하게도 함수나 자료형을 제대로 써 보게 되는 기회가 되었다. Swift를 통해 문자열을 자유자재로 다뤄볼 수 있는 좋은 문제였다.
거의 다 풀어서 입력한 문자가 모두 잘 출력되었는데, 에러의 경우에 "Error!"를 "Error"로 잘못 출력하여 이를 찾기까지 3~4시간을 헤맸다. 문제 좀 잘 읽자 하...
'코딩 테스트 > 백준' 카테고리의 다른 글
[백준] (Python/Swift) 3040번: 백설 공주와 일곱 난쟁이 (0) | 2023.03.25 |
---|---|
[백준] (Swift) 1157번: 단어 공부 (0) | 2023.03.22 |
[백준] (Swift) 10872번: 팩토리얼 (재귀 vs 반복) (2) | 2023.03.18 |
[백준] (Swift) 10769번: 행복한지 슬픈지 (0) | 2023.03.18 |
[백준] (Swift) 10818번: 최소, 최대 (0) | 2023.03.17 |
댓글