잡다한 시도/코테 준비는 하는거니?

[프로그래머스] [python] 전화번호 목록

GGOBOOGI 2021. 5. 5. 17:51
반응형

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

 

코딩테스트 연습 - 전화번호 목록

전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다. 전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다. 구조

programmers.co.kr

문제 이해

배열에 있는 스트링 중, 한 스트링이 다른 스트링의 접두어가 되는게 있냐?를 찾는 문제이다.

 

나의 풀이

def solution(phone_book):
    answer = True
    
    # 접두어 순서대로 정렬함
    phone_book.sort()
    
    for idx in range(1, len(phone_book)):
        # 이전의 len이 지금의 len보다 크면 이전 번호가 지금 번호의 접두어가 될 수 없음
        if(len(phone_book[idx - 1]) > len(phone_book[idx])):
            continue
        
        if(phone_book[idx - 1] == phone_book[idx][:len(phone_book[idx - 1])]):
            answer = False
            break
    
    return answer

일단 입력이 stirng으로 된 list임을 확인하였다.

string 으로 구성된 list를 기본 sort 하게 되면, string 오름차순에 따라 정렬이 된다.

 

만약, ["123",  "88", "12",  "567", "888"] 의 입력에서는 정렬 후 ["12", "123", "567", "88", "888"] 형태를 갖추게 된다.

 

string 내용에 따른 오름차순 정렬이 되므로 나를 접두어로 가질 확률이 있는 애들은 내 뒤에 위치하게 된다.

또한, 위의 예시에서 "567" 뒤에 "88"이 오는 것을 보면, 일단 두 string의 앞자리가 다르면 접두어가 될 가능성이 없겠지만

딱 봤을 때 앞에 있는 길이가 뒤에 있는 string의 길이보다 길면 접두어가 될 가능성이 없다. 왜냐하면 오름차순 정렬이기 때문이다.

 

그래서 나는 일단 정렬을 한 뒤, 앞에 있는 len이 뒤에 있는 len보다 길면 접두어가 될 가능성이 없으니 skip하도록 했다.

만약 접두어가 될 가능성이 있다면, 앞에 있는 len이 뒤에 있는 len보다 짧거나 같을 것이므로 

뒤에 있는 string을 앞의 len만큼 앞에서부터 잘라서 두 string이 같은지를 비교해보면 된다.

 

다른 사람의 풀이

zip(list1, list2)

나는 이거 풀다가 python의 list 내용 하나씩 뽑아서 쓰는 for x in list_name 을 쓰고 싶었는데, 두개씩 뽑아야 해서 어떡하지? 하고 그냥 index로 했었다.

 

근데 프로그래머스에서 제공하는 다른 사람의 풀이를 보고 zip이 생각났다.

 

zip을 뭐라고 설명하지.. 그냥 다음의 예시를 보자.

list1 = [1, 2, 3]
list2 = ['a', 'b']

for x, y in zip(list1, list2):
    print(x, y)
    
    
"""
실행결과

1 a
2 b
"""

이렇게 리스트 두개 이상의 원소를 iter하게 해 주는!!!! 갓 zip이다.

만약 두 리스트의 길이가 다르다면, 짧은 리스트의 길이에서 끝나는 것을 유념할 것.

 

그럼 위에 내가 썼던 풀이처럼 저렇게 idx를 이용해서 구질구질하게 하지 않고

def solution(phone_book):
    answer = True
    
    # 접두어 순서대로 정렬함
    phone_book.sort()
    
    for prev, next in zip(phone_book, phone_book[1:]):
        if(len(prev) > len(next)):
            continue
        
        if(prev == next[:len(prev)]):
            answer = False
            break
    
    return answer

이렇게 깔끔하게!!!!!! 풀 수 있다. 

 

str1.startwith(str2)

이것도 프로그래머스 다른 사람의 풀이를 보고 살짝 현타가 온 것인데,

나는 열심히 오목조목 string을 잘라서 야야 뒤에꺼가 앞에걸로 시작하니?를 물어봤다면

사실 그냥 그 기능을 하는 함수가 있다. ^^

 

이 함수는 야야 str1이 str2로 시작하니? T/F를 물어보는 함수이다....

 

그럼 이걸 이용하면

def solution(phone_book):
    answer = True
    
    # 접두어 순서대로 정렬함
    phone_book.sort()
    
    for prev, next in zip(phone_book, phone_book[1:]):
        if next.startswith(prev):
            answer = False
            break
    
    return answer

이렇게 더 깔끔하게^^^^^^... 풀 수 있다. 현타

 

분발하도록 하자.

오랜만에 코테 풀어봤더니 음.. 코드 어떻게 쓰더라 이러고 앉았음

반응형