-
Programmers Lv2) [2021 카카오블라인드] 신규 아이디 추천Algorithm/Programmers 2021. 2. 22. 13:38728x90
출처: programmers.co.kr/learn/courses/30/lessons/72410
분류: 문자열
접근방식
친절하게 단계별로 요구사항을 제시해주고 있기 때문에 주어진 대로 열심히 구현하면 되는 문제였습니다!
문자열을 다루는 문제이니 만큼 굉장히 다양한 풀이들이 있더라구요. 문자열을 연습하기 아주 좋은 문제였던 것 같아요. 각 단계별로 가능한 다양한 풀이를 생각해보면서 정리해보고자 합니다.
우선 다른 분들의 풀이를 보면 그냥 solution 함수에 다 때려박아(?)서 구현하신 분도 있고 함수를 나누신 분도 계시고 extension 으로 처리해서 더 깔끔하게 푸신 분들도 계시던 것 같아요. 편한대로 풀면 되겠지만 실전이라면 여기서 너무 시간을 오래 끌지 않도록 익숙하고 빠르게 풀 수 있는 방법으로 우선 풀고 다른 문제에 더 시간을 쏟는 편이 좋을 것 같아요. 작년에 저는 쓸데없이 여기서 시간을 꽤나 많이 버렸던 기억이 있네요... 😭
단계 1. 소문자 치환
이건 swift에서 제공해주고 있는 기능이 있어 간단하게 처리가 가능할 것 같아요. 짝꿍인 대문자 치환도 있겠죠?
lowercased() , uppercased()
func replaceWithLowercase(_ text: String) -> String { return text.lowercased() }
단계 2. 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거
이 부분은 다양한 풀이가 있을 수 있겠는데요,
우선 저는 원하는 문자열로 Set을 만들어 필터를 걸어주는 방식을 사용했습니다.
Set<Character>("0123456789abcdefghijklmnopqrstuvwxyz-_.")
func removeInValidChacters(_ text: String) -> String { let validCharacters = Set<Character>("0123456789abcdefghijklmnopqrstuvwxyz-_.") return text.filter { validCharacters.contains($0) } }
다른 풀이로 앞서 소문자로 치환해주고 온 다음이기 때문에 문자열인지 or 숫자인지 or - _ . 인지 확인해주는 or 조건문으로 filter를 걸어주는 방법도 있겠네요.
text.filter { $0.isLetter || $0.isNumber || "-_.".contains($0) }
단계 3. 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.
저는 이 부분은 그냥 for문을 돌려서 이전 문자를 저장해뒀다가 "."일 때를 체크해서 문자열을 다시 만들어가는 방식으로 풀어봤습니다.
func replaceContinouseCommaToOne(_ text: String) -> String { var validString = "" var previous: Character = " " for char in text { if char == ".", previous == char { continue } else { previous = char validString.append(char) } } return validString }
"."이 여러 개 연속된다는 건 ".." 가 있다는 의미이고 이걸 "."로 계속 바꿔나가도 중복을 제거할 수 있습니다.
while text.contains("..") { text.replacingOccurrences(of: "..", with: ".") }
단계 4. 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.
우선 저는 그냥 처음과 끝이 "." 인지 if문으로 확인해서 제거했습니다.
func removeCommaAtFirstOrLast(_ text: String) -> String { var validText = text if validText.first == "." { validText.removeFirst() } if validText.last == "." { validText.removeLast() } return validText }
Swift의 String에서는 prefix와 subfix에 관련된 문법도 제공합니다 :)
if validText.hasSuffix(".") { validText.removeFirst() } if validText.hasSuffix(".") { validText.removeFirst() }
이런 경우는 실제 상황에서도 많이 사용되는 모양이에요. 친절하게도 아예 양 끝을 바로 처리해주는 문법도 제공합니다.
trimmingCharacters 는 다음과 같이 설명이 되어있습니다 :)
Returns a new string made by removing from both ends of the String characters contained in a given character set.
func removeCommaAtFirstOrLast(_ text: String) -> String { return text.trimmingCharacters(in: ["."]) }
단계 5. 빈 문자열이라면, new_id에 "a"를 대입합니다.
이건 뭐 어렵지 않게 가능하겠죠?
func replaceAIfEmpty(_ text: String) -> String { return text.isEmpty ? "a" : text }
단계 6. 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다. 만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다.
저는 길이가 16자 이상이라면 dropLast를 사용해 15자만 남기도록 해주고 마지막이 "."인지 한 번 더 확인해줬습니다.
func removeLongString(_ text: String) -> String { var validText = text if validText.count >= 16 { validText = String(validText.dropLast(validText.count - 15)) } if validText.last == "." { validText.removeLast() } return validText }
15 번째의 인덱스를 얻어서 서브스크립트로 해줄 수도 있겠네요!
func removeLongString(_ text: String) -> String { var validText = text if validText.count >= 16 { let endIndex = text.index(text.startIndex, offsetBy: 15) validText = String(text[text.startIndex..<endIndex]) } if validText.last == "." { validText.removeLast() } return validText }
단계 7. 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.
while문을 사용해 길이가 3보다 작다면 계속 마지막 글자를 붙여주도록 해줬습니다.
func repeatLastToThreeLength(_ text: String) -> String { var validText = text while validText.count < 3 { validText.append(validText.last!) } return validText }
배운점
문자열은 꼭 정복하고 익숙해져야 한다 🔥
너무 시간을 많이 뺏기지 않도록 연습하자.
'Algorithm > Programmers' 카테고리의 다른 글
Programmers Lv3) [2019 카카오블라인드] 길 찾기 게임 (0) 2021.04.21 Programmers Lv2) [2021 카카오블라인드] 메뉴 리뉴얼 (0) 2021.02.27 Programmers Lv4) [2020 카카오블라인드] 가사검색 (0) 2020.08.30 Programmers Lv2) [3차] n진수 게임 (0) 2020.08.28 Programmers Lv2) 파일명 정렬 (0) 2020.08.28