문제의 조건
금지된 단어를 제외한 가장 흔하게 등장하는 단어를 출력하라. 대소문자 구분을 하지 않으며, 구두점(마침표, 쉼표) 또한 무시한다.
📌 (잘못된) 풀이 1(문자의 길이가 1인 테스트 케이스 미통과)
collections 모듈은 기본적으로 파이썬에 내장되어있는 내장 함수이다.
따라서 따로 설치가 필요 없다.
collections.Counter(a)
a에서 요소들의 개수를 세어, 딕셔너리 형태로 반환한다. {문자 : 개수} 형태
import collections
a = [1, 2, 3, 4, 1, 5, 3, 1, 3, 4, 2, 3]
print(collections.Counter(a))
...
Counter({3: 4, 1: 3, 2: 2, 4: 2, 5: 1}))
collections.Counter(a).most_common(n)
a의 요소를 세어, 최빈값 n개를 반환한다. 리스트에 담긴 튜플 형태
import collections
a = [1, 1, 1, 2, 3, 2, 3, 245, 9]
print(collections.Counter(a).most_common(3))
...
[(1, 3), (2, 2), (3, 2)]
풀이
- 우선 words = []를 만들어 input 문장을 공백을 기준으로 나눠준다.
- 나누어진 단어들을 다시 한 문자열씩 탐색해 isalnum을 통해 구두점을 거르어주고 소문자로 저장해준다
- 마지막으로 금지된 단어를 제외시켜준다
이것이 3개의 각 for문에서 하는 역할이다.
거의 모든 테스트 케이스가 통과되었지만 만약 input : paragrah = "a." , banned = [] 일 경우에
index error가 발생한다.
따라서 오답.
import collections
words = []
for word in paragraph.split(' '):
words.append(word)
fin_words = []
for word in words:
fin_words.append(''.join(s for s in word if s.isalnum()).lower())
final_words = []
for word in fin_words:
if word != banned[0]:
final_words.append(word)
counts = collections.Counter(final_words)
print(counts.most_common(1)[0][0])
📌 풀이 2 (정답)
정규표현식 re.sub을 이용한 풀이이다. re.sub은 치환을 해주는 정규표현식이라고 생각하면 된다.
re.sub(정규 표현식, 치환 문자 , 대상 문자열 )
정규 표현식 - 검색 패턴을 지정
치환 문자 - 변경하고 싶은 문자
대상 문자열 - 검색 대상이 되는 문자열
words = [word for word in re.sub('[^\w]',' ',paragraph).lower().split() if word not in banned]
이 구문은 [^\w]을 해석하는 게 중요한데, ^은 아니다(not)를 의미한다. 따라서 이 문장은 paragraph의 word들 중 banned에 들어있지 않은 단어들 중 단어 문자가 아닌 모든 문자를 공백으로 치환한다라는 의미가 된다.
(오히려 한글로 해석하는 것보다 리스트 컴프리헨션을 보면서 직관적으로 해석하는 것이 편할 것이다.)
그다음부터는 풀이 1과 같다.
import collections
import re
paragraph = "Bob hit a ball, the hit BALL flew far after it was hit."
banned = ["hit"]
words = [word for word in re.sub('[^\w]',' ',paragraph).lower().split() if word not in banned]
count = collections.Counter(words)
print(count.most_common(1)[0][0])
# words = ['bob', 'a', 'ball', 'the', 'ball', 'flew', 'far', 'after', 'it', 'was']
# count = Counter
# ({'bob': 1,
# 'a': 1,
# 'ball': 2,
# 'the': 1,
# 'flew': 1,
# 'far': 1,
# 'after': 1,
# 'it': 1,
# 'was': 1})
'Algorithm' 카테고리의 다른 글
리트코드(LeetCode) 5번 가장 긴 팬린드롬 부분 문자열(Longest Palindromic Substring) (0) | 2021.09.13 |
---|---|
리트코드(LeetCode) 49번 그룹 애너그램(Group Anagrams) (0) | 2021.09.09 |
백준 알고리즘 파이썬(Python) 6603번 로또 (0) | 2021.09.05 |
백준 알고리즘 파이썬(Python) 10819번 차이를 최대로 (0) | 2021.09.05 |
리트코드(LeetCode) 937번 로그 파일 재정렬(Reorder Data in Log Files) (0) | 2021.09.02 |