본문 바로가기
Study/Algorithm

[LeetCode] #819. Most Common Word (python)

by 투말치 2022. 2. 17.

목차

    반응형

    문제

    https://leetcode.com/problems/most-common-word/

     

    Most Common Word - LeetCode

    Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

    leetcode.com

    주어진 문단에서 금지된 단어들을 제외하고 가장 자주 나온 단어를 소문자로 반환하는 문제다.

     

    예시 입출력값

    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] 이렇게 인덱스를 두번 접근해야한다.

     

     

    참고한 책 : 파이썬 알고리즘 인터뷰

     
    반응형