2019년 5월 27일 월요일

#38 알고리즘연습 전화번호 목록 python

전화번호 목록


문제 설명
전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다.
전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다.
  • 구조대 : 119
  • 박준영 : 97 674 223
  • 지영석 : 11 9552 4421
전화번호부에 적힌 전화번호를 담은 배열 phone_book 이 solution 함수의 매개변수로 주어질 때, 어떤 번호가 다른 번호의 접두어인 경우가 있으면 false를 그렇지 않으면 true를 return 하도록 solution 함수를 작성해주세요.
제한 사항
  • phone_book의 길이는 1 이상 1,000,000 이하입니다.
  • 각 전화번호의 길이는 1 이상 20 이하입니다.
입출력 예제
phone_bookreturn
[119976742231195524421]false
[123,456,789]true
[12,123,1235,567,88]false
입출력 예 설명
입출력 예 #1
앞에서 설명한 예와 같습니다.
입출력 예 #2
한 번호가 다른 번호의 접두사인 경우가 없으므로, 답은 true입니다.
입출력 예 #3
첫 번째 전화번호, “12”가 두 번째 전화번호 “123”의 접두사입니다. 따라서 답은 false입니다.

알림
2019년 5월 13일, 테스트 케이스가 변경되었습니다. 이로 인해 이전에 통과하던 코드가 더 이상 통과하지 않을 수 있습니다



문제풀이 IDEA

리스트내 원소를 차례대로 탐색하며 list안에 있는지 확인하는 것은 메서드를 이용하면 되지만
해당 문제는 substring인 것을 찾는 문제였다.
그래서 python 의 in을 사용하여 substring유무를 판단해 주었고

["ab", "a" , "c"] 이런 list가 있다고 하면 0번째 index는 1번째 index의 substring이 되지 않지만 1번째 index는 0번째 index의 substring이 되므로

각각의 index에 대해서 나머지 원소들과 모두 비교를 해줬다.

그런데 테스트 케이스를 돌려보니 특정 case에 대해 기댓값과 다르게 결과가 나왔다

그 이유는 접두어라는 문제의 조건때문이었는데
따라서 접두어의 길이만큼 slice를 해서 비교를 해주도록 하자


나의 코드

def solution(p):
for i in p: #입력받은 phone_book의 원소를 하나하나 가져온다
for j in p: #다른 number와 비교해주기 위해서 이중 for문을 사용해줬다
if i == j: #우리는 접두어로 오는 경우만 체크해주므로 같은 경우에는 continue를 해준다
continue #그런데 이때 ["123","123"] 이런 경우에도 접두의 의미랑은 안 어울리므로 continue로 넘긴다.
if i == j[:len(i)]: #접두어니까 비교자하는 대상에서 앞부분 i만큼의 길이만 잘라서 비교해주자
return False
return True


다른 코드


def solution(phoneBook):
phoneBook = sorted(phoneBook) #탐색하는 시간을 줄여주기 위해서 먼저 sorted를 해준다 그럼 ['123','12','56'] => ['12','123','56']
#이렇게 정렬되어 접두어를 찾기 쉬워진다
for p1, p2 in zip(phoneBook, phoneBook[1:]): #zip은 zip([1,2,3],[5,6]) 일때 [(1,5),(2,6)] 이런식으로 iterable object로 return해주게된다.
if p2.startswith(p1): # string.startswith(value, 옵션 : 찾기 시작할 index, 옵션: 찾기 끝낼 index)
return False # 즉 p2 스트링이 p1으로 시작하는지 == p1이 p2의 접두어인지 판단하는 method
return True



정규표현식 코드

import re #파이썬에서 정규표현식을 지원하는 모듈

def solution(phoneBook):

for b in phoneBook:
p = re.compile("^"+b) #"^"+b라는 정규표현식을 compile해서
#컴파일 된 패턴객체를 이용한다

for b2 in phoneBook:
if b != b2 and p.match(b2): #b2의 접두부분이 "^"+b와 매치되는지 판별한다 물론 b와 b2는 다른 애여야한다.
return False #이때 ^b가 나타내는 것은 b2가 ^b 즉 시작하는 부분이 b로 시작해야함을 나타낸다.
return True #반대로 b$는 문자열 마지막에 b가 옴을 나타낸다.

이렇게 정규표현식을 이용해서 해줄 수도 있다.


출처: 프로그래머스

댓글 없음:

댓글 쓰기

가장 많이 본 글