[LeetCode] #290. Word Pattern
문제 :
두개의 문자열들이 인자로 주어지고, 첫번째 문자열과 두번째 문자열의 패턴이 같으면 True를 리턴하고, 다르다면 False를 리턴한다. 이건 너무 쉬운 문제라 보자마자 딕셔너리가 생각났다.
아래는 내가 제출해 통과한 코드이다.
class Solution:
def wordPattern(self, pattern: str, s: str) -> bool:
pattern_list = list(pattern)
s_list = s.split()
word = {}
if len(pattern_list) != len(s_list):
return False
for pattern, s in zip(pattern_list, s_list):
if pattern in word:
if word[pattern] != s:
return False
elif(s not in word.values()):
word[pattern] = s
else:
return False
return True
- 먼저, 주어진 파라미터를 보면 리스트나 튜플같은 시퀀스 객체(순서가 있어 인덱스로 참조 할 수 있는 객체)가 아니라 그냥 문자열로 주어졌기 때문에 우선 이 문자열들을 필요한 기준으로 나누어 리스트로 만들어줘야 한다.
- pattern_list는 인자로 주어진 pattern이라는 문자열을 한 글자씩 추출해 리스트로 반환한다. 예를들어, 문자열이 'abcd'이고, 이 문자열을 list()를 통해 변환시키면 리스트에는 ['a', 'b', 'c', 'd']가 담길 것이다.
- 두번째 문자열은 첫번째 문자열과 약간 다르다. 첫번째 문자열은 그냥 문자 하나씩 기준으로 나누어주면 됐지만, 두번째 인자로 주어진 문자열은 공백을 기준으로 문자가 나뉘어져 있고, 한 글자씩 뽑아야 할게 아니라 공백을 기준으로 나누어진 단어들을 가져와야 하기 때문에 파이썬의 .split()함수를 써서 문자열을 공백을 기준으로 나누어 리스트에 담아주었다. 여기서 만약 쉼표나 다른 구분자를 기준으로 나누고싶다면, split()함수의 파라미터로 구분자를 넘겨주면 된다. 예를들어, 쉼표를 기준으로 문자열을 나누고 싶다면, split.(',')와 같이 쓰면 된다.
- 다음으로, 패턴과 문자를 짝지어 매핑할 빈 딕셔너리를 선언해준다.
- for문을 순회하며 조건을 체크한다.
- 여기서 이전에 썼던 아주 유용한 메서드와 기술(?)을 써먹을 수 있었다 ㅎㅎ 바로 zip과 for a, b! 왜냐하면 우리는 반복문을 돌며 패턴 리스트와 문자 리스트와 비교를 계속 해 주어야 하기 때문에 두개를 동시에 비교 할 수 있도록 zip과 2개의 피연산자를 지정해주었다.
- 반복문을 돌며, 만약 패턴이 딕셔너리 안에 존재한다면, 패턴에 대응하는 value가 현재 문자와 같은지 확인한 후, 그렇지 않으면 False 를 반환한다.
- 만약 패턴이 딕셔너리 안에 존재하지 않는다면, 이제 이 패턴과 현재 루프에서 비교중인 문자를 매핑하여 딕셔너리에 넣어주어야 하는데,
그 전에 이미 그 value가 딕셔너리 안에 있는지 확인 해준다. 예를들어 pattern이 'aabb'이고, 문자가 'dog dog dog dog'일때를 살 펴보자. 세번째 루프(aabb에서 첫번째 b와 문자에서 세번째 dog을 돌고있는 루프)에선 'b'는 딕셔너리 안에 존재하지 않으므로 그대 로 딕셔너리 안으로 들어가게 되어 딕셔너리는 {'a':dog, 'b':dog}과 같이 패턴이 망가지게 된다. 여기서의 패턴은 일대일 대응이지만, 이 예시에서는 일대일 대응이 될 순 없다. 그래서! 한가지 체크를 더 해준다. 지금 딕셔너리에 넣고자 하는 단어가 이미 딕셔너리 안에
있는지 확인 한 후, 없다면 딕셔너리 안에 매핑을 시켜 넣어주고, 있다면 더이상 일대일 대응이 아니므로 False를 반환한다.