programmers.co.kr/learn/courses/30/lessons/64064
문제 설명
user_id 중에서 banned_id에 의해 필터링되는 user_id 목록의 경우의 수를 구하는 문제입니다.
문제의 설명이 꽤 길어서 링크를 함께 첨부하였습니다
자세한 문제 설명은 위 링크를 참조하세요!
풀이 과정
문제에서 배열의 범위가 굉장히 작기 때문에, 완전탐색을 이용하여 풀어도 됩니다!
그래서 저는 순열(permutation)을 이용하여 user_id로 만들 수 있는 모든 경우의 수를 banned_id와 비교하였습니다.
아래 코드의 solution부분부터 보게되면,
permutations(user_id, len(banned_id))를 통해 banned_id 배열의 길이만큼을 user_id에서 뽑아냅니다.
예를들어, banned_id = ["fr*d*", "abc1**"] 이면 user_id에서 두 개를 뽑아내겠죠?
그 다음 뽑은 user_id와 banned_id를 비교합니다. 그 부분이 check함수입니다.
check 함수로 이동하여,
banned_id의 원소와 candidates의 원소를 하나씩 비교하는데,
두 원소의 길이가 다르다면, 당연히 일치하지 않기 때문에 False처리를 해주고
일치하는 경우, 문자 하나하나 따져가며 검사합니다.
banned_id[i]의 n번째 인덱스가 별표인경우는 그 인덱스는 모든 문자가 가능하므로 continue해주고,
두 원소의 똑같은 인덱스의 문자가 일치하지 않는 경우, False 처리를 해줍니다.
모든 for문을 통과하면 True를 리턴합니다.
다시 solution의 check로 돌아와보면, if문을 True로 통과했기 때문에
candidates라는 변수를 set형식으로 바꿔줍니다. ( 중복 방지를 위해 )
그리고 이 candidates가 answer에 없으면, answer에 추가해주면 됩니다.
from itertools import permutations
def check(candidates, banned_id):
for i in range(len(banned_id)):
if len(candidates[i]) != len(banned_id[i]):
return False
for a, b in zip(candidates[i], banned_id[i]):
if b == "*":
continue
if a != b:
return False
return True
def solution(user_id, banned_id):
answer = []
for candidates in permutations(user_id, len(banned_id)):
if check(candidates, banned_id):
candidates = set(candidates)
if candidates not in answer:
answer.append(candidates)
return len(answer)
전체 문제 & 코드는 위의 깃에 정리되어 있습니다.
팔로우 & 맞팔은 환영입니다 !
'Algorithm > Implementation' 카테고리의 다른 글
[백준] 1747 소수&팰린드롬 (Python 파이썬) (0) | 2021.04.27 |
---|---|
[백준] 5525 IOIOI (Python 파이썬) (3) | 2021.04.26 |
[백준] 2869번 달팽이는 올라가고 싶다 (Python 파이썬) (0) | 2021.04.12 |
[백준] 1193 분수찾기 (Python 파이썬) (0) | 2021.04.12 |
[백준] 5212 지구온난화 (Python 파이썬) (0) | 2021.01.29 |