본문 바로가기
Algorithm/LEET CODE ( 파이썬 알고리즘 인터뷰)

[LEET CODE] 819. Most Common Word ( 정규표현식 )

by newnu 2021. 3. 15.
반응형

#Problem

Given a string paragraph and a string array of the banned words banned, return the most frequent word that is not banned. It is guaranteed there is at least one word that is not banned, and that the answer is unique.

The words in paragraph are case-insensitive and the answer should be returned in lowercase.

 

Example 1:
Input :
paragraph : "Bob hit a ball, the hit BALL flew far after it was hit." , banned = ["hit"]
Output : "ball"
Explanation : "hit" occurs 3 times, but it is a banned word.
"ball" occurs twice (and no other word does), so it is the most frequent non-banned word in the paragraph. 
Note that words in the paragraph are not case sensitive,
that punctuation is ignored (even if adjacent to words, such as "ball,"), 
and that "hit" isn't the answer even though it occurs more because it is banned.

Constraints:

  • 1 <= paragraph.length <= 1000
  • paragraph consists of English letters, space ' ', or one of the symbols: "!?',;.".
  • 0 <= banned.length <= 100
  • 1 <= banned[i].length <= 10
  • banned[i] consists of only lowercase English letters.

 

# My Answer

import collections
import re

class Solution:
    def mostCommonWord(self, paragraph: str, banned: List[str]) -> str:
        paragraph = re.sub('[^a-zA-Z0-9]'," ",paragraph) # 정규표현식 이용 특수문자 제거
        paragraph = paragraph.lower().split() # 소문자로 바꾼 후 단어로 나누기

        for ban in banned:
            while(ban in paragraph):   # paragraph에 있는 모든 금지단어 제거하기
                paragraph.remove(ban)

        words = collections.Counter(paragraph) # counter 모듈 이용하여 단어별 개수 세기
        return words.most_common(1)[0][0] # 가장 많이 나오는 단어 첫번째 
        				  #[["단어",횟수]] 이므로 [0][0]으로 단어만 추출

 

# Solution 1

import collections
import re

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]

[^a-zA-Z0-9] -> [\W]로 표현 가능


#  정규 표현식

 

   1) 정규 표현식 문법

. 한개의 임의의 문자( 줄바꿈 \n 제외)
? 앞의 문자가 0개 또는 1개
* 문자가 0개 이상
+ 앞의 문자가 최소 1개 이상 존재 ( 문자가 1개 이상)
^ 뒤의 문자로 문자열이 시작
$ 앞의 문자로 문자열이 끝
{숫자} 숫자만큼 반복
{숫자1,숫자2} 숫자1이상 숫자2 이하만큼 반복. ? . + 대체 가능
{숫자,}  숫자 이상만큼 반복
[]  대괄호 안의 문자들 중 한 개와 매치 (범위도 가능)
[^문자]  해당 문자 제외한 문자 매치
|  (A|B) A 또는 B

 

<역슬래시 이용 규칙> 

\\ 역 슬래쉬 문자 자체  
\d 모든 숫자  [0-9]와 동일
\D 숫자를 제외한 모든 문자  [^0-9]와 동일
\s 공백  [\t\n\r\f\v]와 동일
\S 공백을 제외한 문자  [^\t\n\r\f\v]와 동일
\w 문자 또는 숫자  [a-zA-Z0-9]와 동일
\W 문자 또는 숫자가 아닌 문자  [^a-zA-Z0-9]와 동일

 

  2) 정규표현식 모듈 함수

       - 생략가능

re.compile( 패턴, 플래그 )  정규표현식 컴파일(파이썬에게 전해주는 역할)
찾고자 하는 패턴이 빈번한 경우 미리 컴파일하면 편리, 속도 up
 re.search( 패턴,문자열, 플래그 ) 문자열 전체에 대해서 정규표현식과 매치되는지
(re.match는 처음부터 검색한다는 점이 다름!) 
re.match( 패턴, 문자열, 플래그) 문자열의 처음이 정규표현식과 매치되는지 매치되면 Match Object 리턴
매치되지 않으면 아무것도 출력되지 않음

match 객체의 메서드 :

group(num) - 인덱스에 해당하는 문자열 결과의 부분집합 반환 
                       0이거나 입력되지 않으면 전체 문자열 반환
groups() - 매칭된 결과를 튜플 형태로 반환
groupdict() - 이름이 붙여진 매칭 결과를 사전 형태로 반환
re.split(패턴, 문자열, 최대 split 수, 플래그)  정규 표현식을 기준으로 문자열을 분리하여 리스트로 리턴
re.findall( 패턴, 문자열, 플래그) 정규표현식과 매치되는 모든 경우의 문자열 리스트로 리턴
없으면 빈 리스트 리턴
re.finditer( 패턴, 문자열, 플래그 )  정규표현식과 매치되는 모든 경우의 문자열에 대한 이터레이터 객체 리턴
re.sub( 패턴,교체할 문자열, 원래 문자열
, 최대 교체수, 플래그) 
정규표현식과 일치하는 부분에 대해서 다른 문자열로 대체

 

** 점프투 파이썬 (wikidocs.net/4308 참고)

** 딥러닝을 이용한 자연어 처리 입문 (wikidocs.net/21703 참고)

 

반응형