1. 문제 파악하기
- new_id는 길이가 1이상 1,000 이하인 문자열이다. → 별로 길지 않은 문자열
- new_id는 알파벳 대문자, 알파벳 소문자, 숫자, 특수문자로 구성되어 있음.
- new_id에 나타날 수 있는 특수 문자는 -_.~!@#$%^&*()=+[{]}:?,<>/ 로 한정. → 이 중에서 앞에 - _ . 만 사용가능하고 나머지는 지워야함
2. 문제 접근하기
이번 문제는 문제에서 주어진 7가지 단계 순서대로 구현하면 쉽게 문제를 해결할 수 있습니다. 코드는 level1 문제치곤 길다고 생각드실 수도 있지만 그렇게 어려운 알고리즘을 생각할 필요는 없다고 생각이 듭니다.
3. 주의할 점
- 입력으로 주어지는 new_id의 길이가 1이상 1,000 이하인 문자열이라서 무한루프에 빠지지만 않는다면 실행시간이 그렇게 오래걸리지 않을 것입니다. 7가지 단계 중 특수 문자 제거, 연속된 마침표를 제거 부분에서 while문을 이용해서 코드를 작성하신 분들이라면 무한루프를 조금 주의해서 코드를 작성하셨어야 할거 같습니다.
- 특수 문자 제거, 마침표 제거 등 문자열을 제거하다보면 빈문자열이 만들어지는 경우가 있을텐데, 이때 인덱싱 에러 문제로 조금 조심해야할 부분인거 같습니다.
4. 정답 코드 및 해석
def solution(new_id):
del_str = ["~", "!", "@", "#", "$", "%", "^", "&", "*","(", ")", "=",
"+", "[", "{", "]", "}", ":", "?", ",", "<", ">", "/"]
#1단계 소문자로 바꾸기
new_id = new_id.lower()
#2단계 특수 문자 제거
index = 0
while index < len(new_id) :
if new_id[index] in del_str :
new_id = new_id.replace(new_id[index], "")
else :
index += 1
#3단계 마침표 2번이상 연속을 하나로 치환
while ".." in new_id :
new_id = new_id.replace("."*2, ".")
#4단계 마침표 처음과 끝에 위치 제거
if len(new_id) > 0 and new_id[0] == "." :
new_id = new_id[1:]
elif len(new_id) > 0 and new_id[-1] == "." :
new_id = new_id[:-1]
#5단계 빈 문자열이면 "a"를 대입
if new_id == "" :
new_id = "a"
#6단계 16자리 이상이면 15까지 남기고 제거 & 끝자리 마침표 제거
if len(new_id) > 15 :
new_id = new_id[:15]
if new_id[-1] == "." :
new_id = new_id[:-1]
#7단계 2자리 이하면 아이디의 마지막 문자 반복
while len(new_id) <= 2 :
new_id += new_id[-1]
return new_id
정답 코드 및 해석입니다. 7가지 단계로 나눠서 작성하다보니 코드가 조금 길어서 단계별로 나눠서 설명을 드리겠습니다.
우선 del_str이라는 리스트가 있습니다. 보시면 아시겠지만 지워야할 특수 문자들이 들어있습니다.
1단계는 대문자로 되어 있는 문자열을 소문자로 바꾸는 과정입니다. 파이썬에서는 .lower() 함수를 이용해서 대문자를 소문자로, .upper() 함수를 이용해서 소문자를 대문자로 바꿀 수 있습니다. 파이썬의 장점중 하나인 유용한 내장함수가 많은 것을 활용하여 1단계는 1줄로 코드를 작성할 수 있습니다.
2단계는 특수 문자를 제거하는 것입니다. index라는 변수에 0을 초기화 시킵니다. 그런 다음 while문을 이용해서 new_id의 한문자씩 확인하면서 del_str에 들어 있는 특수 문자라면 replace("지울 문자", "지운 문자 대신 바꿀 문자") 함수를 이용해서 제거시킵니다. 다른 라이브러리를 사용하여 해결할 수 있는 방법도 있지만 import를 사용하지 않고 그냥 내장함수만을 이용해서 코드를 작성한다면 이렇게 간단한 방법이 있을거 같습니다. 어차피 new_id의 최대 길이가 1,000 밖에 안되니 큰 문제는 될거 같지 않습니다.
3단계는 마침표가 2번이상 연속된 부분을 하나로 치환하는 것입니다. 저는 개인적으로 이 부분을 가장 까다롭다고 생각했는데요. '어떻게하면 간단하고 짧게 해결할 수 있을까?' 생각했던거 같습니다. 제가 생각한 방법은 while문을 사용하여 new_id에 ".."이 있으면 "."으로 치환하는 방법입니다. "..."이더라도 앞의 ".."이 먼저 인식이 되서 ".."으로 바뀔 것이고 이는 한번 더 while문에 걸려서 "."으로 바뀝니다.("..." → ".." → ".") 이렇게 하면 3단계 코드도 간단하게 완료 할 수 있습니다.
4단계는 마침표가 처음이나 끝에 위치하면 제거하는 단계입니다. 이 부분은 인덱싱을 이용하면 쉽게 제거 할 수 있어서 다들 쉽게 하셨을거 같습니다. 저는 앞에 과정 때문에 길이가 0인 new_id일 경우 new_id[0]과 new_id[-1] 코드가 인덱싱 에러가 방생하여 앞에부분에 len(new_id) > 0이라는 조건을 넣어줬습니다.
5단계는 빈 문자열이면 "a"를 대입하는 단계입니다. 이 부분은 if문을 사용하시면 쉽게 하실 수 있는 부분이니 넘어가겠습니다.
6단계는 16자리 이상이면 15자리까지 남기고 나머지는 제거 & 끝자리에 마침표가 있으면 제거하는 단계입니다. 이부분도 if문을 사용하면 쉽게 구현할 수 있습니다. new_id가 15자리 초과라면 new_id를 슬라이싱하여 0~14까지 자릅니다. 그런 다음 new_id의 끝자리에 "."이 있으면 제거해줍니다.
마지막 7단계는 new_id가 2자리 이하라면 new_id의 마지막 문자를 반복하여 new_id의 길이를 3으로 만드는 단계입니다. 이 부분도 while, if문을 사용하면 쉽게 구현할 수 있었습니다.
이렇게 코드를 작성하면 다음과 같은 결과로 통과를 할 수 있었습니다.
5. 마치며
이번 문제도 크게 어려운 부분은 없었습니다. 빈문자열 처리, 무한루프에 빠지지만 않으셨다면 금방 해결하셨을거 같습니다. 저는 replace(), lower() 등을 사용하여 쉽게 구현했는데 내장 함수를 잘 모르시면 힘드셨을거 같습니다. 파이썬을 사용하신다면 파이썬의 큰 장점 중 하나인 내장 함수를 익히셔서 유용하게 사용하는 것을 추천드립니다. 내장 함수가 많은 만큼 기능은 비슷하지만 시간 복잡도, 공간 복잡도가 차이가 나는 함수들이 있습니다. 이런 것들을 잘 알고 비교해서 사용하신다면 시간초과가 나는 문제를 잘 해결하실 수도 있습니다.
'CS > Algorithm' 카테고리의 다른 글
프로그래머스 level2 메뉴 리뉴얼 (0) | 2021.02.13 |
---|---|
프로그래머스 level2 주식 가격 (0) | 2021.02.12 |
내가 Python을 사용하는 이유 (0) | 2020.11.23 |
프로그래머스 Level 1 두개 뽑아서 더하기 (0) | 2020.11.23 |
프로그래머스 Level 1 완주하지 못한 선수 찾아내기 (0) | 2020.11.22 |