algo lev-2 전화번호 목록 (python)
전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다. 전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다.
- 구조대 : 119
- 박준영 : 97 674 223
- 지영석 : 11 9552 4421
전화번호부에 적힌 전화번호를 담은 배열 phone_book 이 solution 함수의 매개변수로 주어질 때, 어떤 번호가 다른 번호의 접두어인 경우가 있으면 false를 그렇지 않으면 true를 return 하도록 solution 함수를 작성해주세요.
출처 : 프로그래머스 Level2
내가 푼 풀이
전화번호부에 적힌 모든 번호들을 각각 비교해야 하는데 이중for문이 가장 쉽기 때문에 for를 사용해서 문제를 풀었다. (으으 이중 for문 싫어….) “접두어”라는 조건때문에 k1, k2 변수에 a와 b 문자열의 길이를 값으로 줬다.
접두어 길이 값을 따로 주기.py
def solution(phone_book):
for a in range(len(phone_book)):
k1 = len(phone_book[a])
for b in range(a+1, len(phone_book)):
k2 = len(phone_book[b])
if phone_book[a] in phone_book[b][:k1] or phone_book[b] in phone_book[a][:k2] :
return False
return True
만약 정렬을 한다면 자연스럽게 짧은 길이의 문자열이 앞으로 오기 때문에 굳이 k1, k2 값을 고려할 필요가 없었다. 비교도 앞-뒤 만 하면 되기 때문에 아래와 같이 수정했다. 또한 정렬을 했기 때문에 이중 for문도 사용할 필요가 없었다 (야호!)
정렬하기.py
def solution(phone_book):
phone_book.sort()
for a in range(len(phone_book)-1):
if phone_book[a] in phone_book[a+1] :
return False
return True
다른 사람의 풀이
startswith().py
def solution(phone_book):
phone_book.sort()
for p1, p2 in zip(phone_book, phone_book[1:]):
if p2.startswith(p1):
return False
return True
배운 점
1) zip() 으로 앞뒤값 비교하기
그동안은 c언어에서 하던 것 처럼 인덱스 값을 받아서 비교를 했는데, zip()
을 이용해 다른 방법으로 표현할 수 있다는 것을 배웠다. 흠, 어떤 방법이 더 빠르고 효과적인지 비교해보고 싶은데, 어떻게 하면 좋을 지 고민해봐야 겠음
2) startswith()
strB.startswith(strA,beg=0,end=len(string))
# strB[beg:end]에서 strA 문자열 찾기!
startswith()은 내가 찾고자 하는 문자열A가 문자열B의 맨 앞에 있는지의 여부를 알려준다! 기본적으로는 문자열 strB에 문자열 strA 가 맨 앞 있다면 True
를 반환하고, 아니라면 False
를 반환한다.
strB = 'abcdefg'
print(strB.startswith('ab')) # True
print(strB.startswith('bcd')) # False
# 찾고자 하는 문자열 'bcd'가 strB의 앞에 없음
(optional) 이때 beg과 end에 값을 줘서, strB의 범위를 조절할 수 있다. 즉 strB[beg:end] 로 슬라이싱한 문자열의 맨 앞과 strA가 같은지 비교하면 된다!
strB = 'abcdefg'
print(strB.startswith('ab', 1)) # False
print(strB.startswith('bcd', 1)) # True
# strB[beg:end]
# strB[1:]은 'bcdefg'가 된다
Comments