Just Fighting

[프로그래머스] 신규 아이디 추천 본문

Algorithm/코딩테스트 연습

[프로그래머스] 신규 아이디 추천

yennle 2022. 1. 9. 22:11
728x90

https://programmers.co.kr/learn/courses/30/lessons/72410

 

코딩테스트 연습 - 신규 아이디 추천

카카오에 입사한 신입 개발자 네오는 "카카오계정개발팀"에 배치되어, 카카오 서비스에 가입하는 유저들의 아이디를 생성하는 업무를 담당하게 되었습니다. "네오"에게 주어진 첫 업무는 새로

programmers.co.kr

 

 

<문제 설명>

아이디를 생성하는데 규칙에 맞지 않는 아이디를 비슷한 아이디로 추천해주려고 한다.

규칙은 다음과 같다.

1. 대문자 -> 소문자

2. 소문자, 숫자, '-', '_', '.' 제외의 문자는 제거

3. '.' 이 연속이면 하나로 치환

4. '.' 이 아이디의 처음과 끝에 붙어있으면 제거

5. 아이디가 비어있으면 "a" 대입

6. 16자 이상 -> 앞 15자 빼고 뒤에 문자 제거, '.'이 마지막 문자면 '.'도 제거

7. 2자 이하 -> 마지막 문자 반복. 길이가 3이 되도록

 

 

 

<문제 이해>

문자열을 가지고 노는 문제이기 때문에

문자열을 다루는 방법에 대해서 잘 알고 있어야 수월하게 풀 수 있다고 생각했다.

 

 

 

< 문제 풀이>

def solution(new_id):
    
    # 규칙 1
    new1 = new_id.lower()
        
    # 규칙 2
    new2 = ""   
    for c in new1:
        if (c >= 'a' and c <= 'z') or (c >= '0' and c <='9') or c in '-_.':
            new2 += c    
    
    # 규칙 3
    new3 = ""
    dotBefore = False
    for c in new2:
        if not dotBefore:
            new3 += c
            if c == '.':
                dotBefore = True
        else:
            if c != '.' : 
                new3 += c
                dotBefore = False
            else:
                dotBefore = True
    
    # 규칙 4
    new4 = new3.strip('.')
    
    # 규칙 5
    new5 = str(new4)
    if len(new4) == 0:
        new5 = 'a'
    
    # 규칙 6
    new6 = str(new5)
    if len(new5) >= 16:
        new6 = new5[:15]
        new6 = new6.rstrip('.')
    
    # 규칙 7
    new7 = str(new6)
    if len(new6) <= 2:
        new7 = new6 + new6[len(new6)-1] * (3-len(new6))
        
    return new7

규칙 2에서 테스트 겸 print()를 계속했는데 테스트 문제에서 '^'가 안지워지고 남아있어서 여기서 엄청 헤맸다,,

그냥 무시하고 다음 코드를 짜고 테스트해보니 그 때는 또 잘 지워졌었다,,,,,,,,,,,,,,,,,,,,,뭐지,,,

규칙 3을 이전에 '.'가 나왔으면 다음 '.'를 문자열에 추가하지 않기 위한 코드로 짰다.

뭔가 좀 더 단순하게 짤 수 있을 것 같았는데 머리가 안돌아갔다ㅎㅎ;;

규칙 7은 문장의 마지막 문자를 반복하는 것이여서 (문자열)*(숫자)의 방식을 이용했다.

 

구분을 위해 일부러 계속 새로운 변수를 넣었더니 뭔가 좀 더 복잡해 보이는 기분이다.

이 부분을 조금 고치고, 조금 더 간단하게 풀 수 있는 방법으로 수정하면 좋을 것 같다.

 

 

<실행 결과>

 

 

<풀이 개선>

위의 문제를 정규표현식을 이용하여 풀 수 있다.

- 규칙2

import re

new_id = re.sub('[^a-z0-9\-_.]','',new_id)

영어 소문자나 숫자나 '-', '_', '.' 가 아니면 ''으로 대체한다(지운다).

[]는 문자들 중 하나를 의미하고 ^는 시작의 의미를 갖지만 대괄호 안에서는 부정의 의미가 된다.

 

- 규칙3

new_id = re.sub('\.+', '.', new_id)

\.+는 .가 하나 이상 포함된 것을 의미한다. 따라서 여러번의 '.'이 나오면 하나로 치환하는 코드이다.

 

- 규칙 4

new_id = re.sub('^[.]|[.]$', '', new_id)

^는 뒤에 오는 문자열로 시작함을 의미하고, $는 앞에오는 문자열로 끝남 의미한다.

따라서 '.'으로 시작하거나 끝나면 없애는 코드이다.

 

 

 

<수정 코드>

import re

def solution(new_id):
    
    answer = new_id.lower()
    answer = re.sub('[^a-z0-9\-_.]','',answer)
    answer = re.sub('\.+','.',answer)
    answer = answer.strip('.')
    answer = answer if len(answer) > 0 else 'a'
    answer = (answer if len(answer) < 16 else answer[:15]).rstrip('.')
    answer = answer if len(answer) > 2 else answer + answer[len(answer)-1] * (3-len(answer))        

    return answer

시간이 조금 더 오래 걸리긴 하지만 코드가 깔끔하고 멋있다,,,ㅎㅎㅎ

 

 

 

내 취약점인 문자열 문제,,,

열심히 해봅시다~!

 

 

참고 : http://www.devholic.net/1000238

728x90
Comments