목차
문제
https://leetcode.com/problems/most-common-word/
주어진 문단에서 금지된 단어들을 제외하고 가장 자주 나온 단어를 소문자로 반환하는 문제다.
예시 입출력값
Input: paragraph = "Bob hit a ball, the hit BALL flew far after it was hit.", banned = ["hit"]
Output: "ball"
풀이
내 풀이
class Solution:
def mostCommonWord(self, paragraph: str, banned: List[str]) -> str:
#대소문자 구분 X
paragraph=paragraph.lower()
re_paragraph=re.sub('[^a-z ]', ' ', paragraph)
li_pa=re_paragraph.split()
set_pa=set(re_paragraph.split())
li_word=[]
for s in set_pa:
if s not in banned:
li_word.append(s)
cnt=[]
for w in li_word:
cnt.append(li_pa.count(w))
return li_word[cnt.index(max(cnt))]
우선 나온 단어들은 set을 이용해서 추출하고 그 중에서 banned에 속하는 단어도 제외했다.
다음으로 단어 개수를 세고 그 중 가장 많이 나온 단어를 반환했다.
처음 제출한건 틀렸는데 특수문자를 제거하는 정규표현식에서 대체할 때 공백으로 대체하지 않고 그냥 없애버리니까 b,b 가 bb로 인식되어서 잘못된 답이 나왔다. 그래서 대체할 때 공백으로 변경하니까 성공했다.
책 풀이
1. 리스트 컴프리헨션 사용
import collections
import re
from typing import List
class Solution:
def mostCommonWord(self, paragraph: str, banned: List[str]) -> str:
words = [word for word in re.sub(r'[^\w]', ' ', paragraph)
.lower().split()
if word not in banned]
counts = collections.Counter(words)
# 가장 흔하게 등장하는 단어의 첫 번째 인덱스 리턴
return counts.most_common(1)[0][0]
words = [word for word in re.sub(r'[^\w]', ' ', paragraph)
.lower().split()
if word not in banned]
paragraph에서 \w 패턴이 아닌 것은 공백으로 치환하고 소문자로 만들고 split하고 banned에 해당 단어가 없으면 리스트의 요소로 넣으라는 뜻
\w 패턴 : [a-zA-Z0-9_]
만 속한다
리스트 컴프리헨션에서 if 문을 쓸 때는 for 보다 뒤에 써야 한다
다른 예시
nums=[i for i in range(5)]
#nums=[0, 1, 2, 3, 4]
2. Counter 객체 사용
Counter는 데이터의 개수를 셀 때 사용하는 Collections 모듈에 있는 클래스다
from collections import Counter
c=Counter('hello, nice to meet you')
print(c)
#출력 : 딕셔너리 형태로 반환
#Counter({'e': 4, ' ': 4, 'o': 3, 'l': 2, 't': 2, 'h': 1, ',': 1, 'n': 1, 'i': 1, 'c': 1, 'm': 1, 'y': 1, 'u': 1})
Counter는 알아서 개수를 세고 딕셔너리 형태로 값과 개수를 반환한다.
Counter의 most_common 함수는 데이터의 개수가 많은 순으로 정렬된 배열을 반환한다.
여기서 인자로 숫자를 넣으면 가장 개수가 많은 n개의 데이터를 얻을 수 있다.
#가장 개수가 많은 10개의 값 출력
Counter(words).most_common(10)
'''출력 :
[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),
('you', 554), ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]
'''
most_common의 출력 형태가 이렇기 때문에 풀이에서 return counts.most_common(1)[0][0]
이렇게 인덱스를 두번 접근해야한다.
참고한 책 : 파이썬 알고리즘 인터뷰
'Study > Algorithm' 카테고리의 다른 글
[LeetCode] #5. Longest Palindromic Substring (python) (0) | 2022.02.21 |
---|---|
[LeetCode] #49. Group Anagrams (python) (0) | 2022.02.20 |
[LeetCode] #937. Reorder Data in Log Files (python) (0) | 2022.02.17 |
[LeetCode] #344. Reverse String (python) (0) | 2022.02.17 |
[LeetCode] #125. valid palindrome (python) (0) | 2022.02.17 |