컴퓨터는 잘못이 없다..

[파이썬 알고리즘 인터뷰]6장_문자열 조작 04_가장 흔한 단어(파이썬 collections모듈의 Counter객체, most_common() 사용법, max()사용법, defaultdict사용법) 본문

공부/알고리즘(파이썬)

[파이썬 알고리즘 인터뷰]6장_문자열 조작 04_가장 흔한 단어(파이썬 collections모듈의 Counter객체, most_common() 사용법, max()사용법, defaultdict사용법)

도토리까꿍v 2021. 5. 16. 15:33
Contents 접기

#이 포스팅에서 암기해야할 것

1. defaultdict 사용하기 

2. collections 모듈의 Counter 객체 

3. Counter객체의 most_common() 사용하는 법

#문제 링크

(3) Most Common Word - LeetCode

 

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

#문제

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.
Example 2:

Input: paragraph = "a.", banned = []
Output: "a"
 

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.


[문제 해설]
금지된 단어를 제외한 가장 흔하게 등장하는 단어를 출력하라.
대소문자 구분을 하지 않으며, 구두점(마침표, 쉼표 등) 또한 무시한다.

[입력]
paragraph = "Bob hit a ball, the hit BALL flew far after it was hit.", 
banned = ["hit"]

[출력]
"ball"

 

#풀이1_1. 리스트 컴프리헨션과 for문 max()로 해결 

class Solution(object):
    def mostCommonWord(self, paragraph, banned):
        #문자외에 다른 문자는 ' '로 바꿔준다.
        #lower()로 모두 소문자로 바꿔준다.
        #split()를 사용해서 공백을 기준으로 리스트 words에 담아준다.
        #단, banned에 속한 문자는 담지 않는다. 
        #ex) words="hello, hellow, hi" words=["hello","hello","hi"]
        words = [word for word in re.sub(r'[^\w]',' ',paragraph).lower().split() if word not in banned]
        
        #defaultdict를 사용해 값의 자료형이 int인 딕셔너리 만들기
        counts=collections.defaultdict(int)
        
        #for문으로 words내의 요소를 하나씩 돌면서 count증가시키기
        for word in words :
            counts[word] += 1 #counts[word]는 int형이므로 +=1 연산 가능
            
        #counts의 값 기준으로 max인 키를 리턴하기 
        return max(counts, key=counts.get)

▲설명

r'[^\w]' : r는 row string으로 뒤에 나오는 문자열이 \가 이스케이프 문자로 해석되는것을 방지한다.

\w는 word character을 뜻하며 ^는 not을 뜻한다.

 

문제는 이렇게 해결했다.

 #풀이1_2. 리스트 컴프리헨션, Counter객체 사용

class Solution(object):
    def mostCommonWord(self, paragraph, banned):
        #문자외에 다른 문자는 ' '로 바꿔준다.
        #lower()로 모두 소문자로 바꿔준다.
        #split()를 사용해서 공백을 기준으로 리스트 words에 담아준다.
        #단, banned에 속한 문자는 담지 않는다. 
        #ex) words="hello, hellow, hi" words=["hello","hello","hi"]
        words = [word for word in re.sub(r'[^\w]',' ',paragraph).lower().split() if word not in banned]
        
        
        #Counter객체를 이용해 words내 요소 개수 세기
        #words=["hello","hello","hi"]라면 counts={'hello' :2, 'hi':1}
        counts=collections.Counter(words)
        
        
        #Counter객체의 most_common이용해 빈도수 가장 높은 요소 뽑기
        return counts.most_common(1)[0][0] #most_common(1) = [('hello',2)] 이므로 리스트의 [0]번째 [0]번째는 'hello'

▲설명

풀이1_1에서 defaultdict와 for문으로 해결했었던 것을 

        #defaultdict를 사용해 값의 자료형이 int인 딕셔너리 만들기
        counts=collections.defaultdict(int)
        
        #for문으로 words내의 요소를 하나씩 돌면서 count증가시키기
        for word in words :
            counts[word] += 1 #counts[word]는 int형이므로 +=1 연산 가능

풀이1_2의 Counter객체를 사용하면 위의 코드를 아래처럼 줄일 수 있다. 

        #Counter객체를 이용해 words내 요소 개수 세기
        #words=["hello","hello","hi"]라면 counts={'hello' :2, 'hi':1}
        counts=collections.Counter(words)

 

 

또한 풀이 1_1에서 max()로 해결했었던 것을

        #counts의 값 기준으로 max인 키를 리턴하기 
        return max(counts, key=counts.get)

 

풀이1_2 most_common()을 이용해 아래처럼 풀 수 있다.

#Counter객체의 most_common이용해 빈도수 가장 높은 요소 뽑기
        return counts.most_common(1)[0][0] #most_common(1) = [('hello',2)] 이므로 리스트의 [0]번째 [0]번째는 'hello'
Comments