카카오 2021 #1 - 신규아이디 추천

📌 문제

  1. 대문자 -> 소문자
  2. 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거
  3. new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환
  4. new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거
  5. new_id가 빈 문자열이라면, new_id에 "a"를 대입
  6. new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거
    ( 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다. )
  7. new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.

📌 아이디어 & 헤맸던 점

기본적인 아이디어는 순서대로 구현하면 된다.

🔥 1. lower() 는 새로운 문자열을 반환한다.

a = "wewADAdwqdqw"

a.lower()

print(a) // wewADAdwqdqw
a = "wewADAdwqdqw"

a = a.lower()

print(a) // wewadadwqdqw

🔥 2. 가장 헤맸던 부분인데, len(a) for loop 안에서 해당 문자열의 길이를 바꾸면 len(a)역시 바뀐다.

changed_id = ".qdqw...."

for i in range(len(changed_id) - 1):
    if changed_id[i] == '.' and changed_id[i + 1] == '.':
        changed_id = changed_id[:i] + changed_id[i + 1:]
    else:
        changed_id = changed_id

print(changed_id)

위 코드는 i를 순회하면서 i가 . 일때, i+1 도 . 이라면 slicing을 이용해서 changed_id 의 값을 갱신하는 코드이다.

그런데 위 코드는 에러가 난다.

changed_id = ".qdqw...."

for i in range(len(changed_id) - 1):
    print("len(changed_id) = " + str(len(changed_id)))
    print(i)
    if changed_id[i] == '.' and changed_id[i + 1] == '.':
        changed_id = changed_id[:i] + changed_id[i + 1:]
    else:
        changed_id = changed_id

print(changed_id)

위와 같이 for loop 안에 print를 넣어보자.

for loop 안에서 해당 문자열의 길이가 바뀌어서, loop의 범위 또한 바뀌었다. 그래서 해당 문자열의 끝까지 loop가 돌게 되고, index out of range 에러가 생긴다.

🔥 개선

index=0
while index<len(changed_id):
    if index != len(changed_id)-1 and changed_id[index]=='.' and changed_id[index+1]=='.':
        index+=1
    elif index != len(changed_id)-1 and changed_id[index]=='.' and changed_id[index+1]!='.':
        changed_three += "."
        index+=1
    else:
        changed_three += changed_id[index]
        index+=1

헷갈리지 않기 위해 changed_three 새로운 문자열을 생성했다.

for loop는 i를 새로 지정해도 정해진 대로 돌으므로, while loop를 이용했다.

  1. i, i+1 = '.' 이라면 넘어가고
  2. i=='.' and i+1 !='.' 이면 .를 추가해줬다.
  3. 그 외에는 그냥 문자열을 추가해주면 된다.

🔥 3. 양쪽 제거

    if len(changed_three) >= 2:
        while changed_three[0] == '.' or changed_three[len(changed_three) - 1] == '.':
            if changed_three[0] == '.' and changed_three[len(changed_three) - 1] == '.':
                changed_three = changed_three[1:len(changed_three) - 1]
            elif changed_three[0] == '.':
                changed_three = changed_three[1:]
            elif changed_three[len(changed_three) - 1] == '.':
                changed_three = changed_three[:len(changed_three) - 1]
    
    if changed_three == ".":
        changed_three = ""

길이가 2 이상일때만 유효하다.

📌 전체코드

# 3 <= len <= 15
# - _ . 알파벳 소문자, 숫자
# .는 처음과 끝 불가능. 연속사용 x

def solution(new_id):
    # 1번 소문자 변환
    new_id = new_id.lower()

    # 2번 알파벳 소문자, 숫자, -, _, . 제외한 문자 제거
    changed_id = ""

    for s in new_id:
        if s.isalpha() or s.isdigit() or s == '-' or s == '_' or s == '.':
            changed_id += s

    changed_three = ""
    # 3-2) 2번 . 이상이면 제거
    # changed_id 가 변화하므로 len(changed_id) 역시 변화함
    # for i in range(len(changed_id) - 1):
    #     if changed_id[i] == '.' and changed_id[i + 1] == '.':
    #         changed_three = changed_id[:i] + changed_id[i + 1:]
    #     else:
    #         changed_three = changed_id
    index=0
    while index<len(changed_id):
        if index != len(changed_id)-1 and changed_id[index]=='.' and changed_id[index+1]=='.':
            index+=1
        elif index != len(changed_id)-1 and changed_id[index]=='.' and changed_id[index+1]!='.':
            changed_three += "."
            index+=1
        else:
            changed_three += changed_id[index]
            index+=1

    # 3번 . 2번이상 제거.  . 맨앞이나 맨 뒤면 제거
    # 3-1) 맨앞이나 맨뒤 . 면 제거
    if len(changed_three) >= 2:
        while changed_three[0] == '.' or changed_three[len(changed_three) - 1] == '.':
            if changed_three[0] == '.' and changed_three[len(changed_three) - 1] == '.':
                changed_three = changed_three[1:len(changed_three) - 1]
            elif changed_three[0] == '.':
                changed_three = changed_three[1:]
            elif changed_three[len(changed_three) - 1] == '.':
                changed_three = changed_three[:len(changed_three) - 1]

    if changed_three == ".":
        changed_three = ""

    if changed_three == "":
        changed_three += "a"

    if len(changed_three) >= 16:
        changed_three = changed_three[:15]

    while len(changed_three) < 3:
        changed_three += changed_three[len(changed_three) - 1]

    while changed_three[len(changed_three)-1] == '.':
        changed_three = changed_three[:len(changed_three)-1]

    # print(changed_three)
    return changed_three


solution("...!@BaT#*..y.abcdefghijklm.")
solution("=.=")
solution("aa")
solution("123_.def")
solution("=weew.q.q")
solution("bb...")

📌 다른 사람 코드

def solution(new_id):
    answer = ''
    # 1
    new_id = new_id.lower()
    # 2
    for c in new_id:
        if c.isalpha() or c.isdigit() or c in ['-', '_', '.']:
            answer += c
    # 3
    while '..' in answer:
        answer = answer.replace('..', '.')
    # 4
    if answer[0] == '.':
        answer = answer[1:] if len(answer) > 1 else '.'
    if answer[-1] == '.':
        answer = answer[:-1]
    # 5
    if answer == '':
        answer = 'a'
    # 6
    if len(answer) > 15:
        answer = answer[:15]
        if answer[-1] == '.':
            answer = answer[:-1]
    # 7
    while len(answer) < 3:
        answer += answer[-1]
    return answer
  1. replace를 쓸 생각을 못했다.

  2. slicing을 더 잘 이용하자.

좋은 웹페이지 즐겨찾기