03_most_common_word

Numeric_combo·2024년 6월 26일

알고리즘-공부

목록 보기
5/6

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.

내가 쓴 거

class Solution:
    def mostCommonWord(self, paragraph: str, banned: List[str]) -> str:
        # make a banned word list
        banned = set(word.lower() for word in banned)

        # get rid of special characters while lowering cases and spliting
        lowered_s = re.sub(r'[^A-za-z0-9]', ' ', paragraph).lower().split()

        # get rid of banned words
        preprocessed = []
        for i in lowered_s:
            if i not in banned:
                preprocessed.append(i)

        # count words
        word_count = {}
        for words in preprocessed:
            if words not in word_count:
                word_count[words] = 0
            word_count[words] += 1
        
        # pick the most frequent word and then return it
        return max(word_count, key = word_count.get)

솔루션

import re

class Solution:
    def mostCommonWord(self, paragraph: str, banned: List[str]) -> str:
		
		# convert to lower case and split string into words by spaces and punctuation
        a = re.split(r'\W+', paragraph.lower())
		
		# make new list consisitng of words not in banned list (remove banned words)
        b = [w for w in a if w not in banned]
		
		# return value that counted max times in the new list
        return max(b, key = b.count)

처음 내가 푼 것의 경우 일단 banned를 하드코딩(내 경우 'hit'이라고 리스트 안에 따로 저장)했는데 오류가 나서 저렇게 했다. 어떻게 할지 몰라서 결국 챗지피티한테 물어보니 저렇게 함..list comprehension을 사용하고 그걸 lower() 시킨 다음 set()으로 씌워서 해당 word를 unique하게 하는 방식이었다. 왜냐하면 banned word 개개는 독립적인 거니깐.

복습 겸 알아둘 것들은 다음과 같다.

단어 세기

  • 단어의 갯수를 세는 방법의 경우, 내 경우에는 저렇게 미리 텅 빈 딕셔너리를 명시화한 다음에 하는 게 있다. 즉, 미리 word_count라는 딕셔너리를 만든 다음, 전처리한 리스트 안에 원소들(=words)이 word_count에 '없다면' word_count의 키로서 각각의 word들은 그 value가 0으로서 지정이 된다. 이후 if 문밖에서 각각의 word가 발견될 때 마다 key로서 저장되어 value가 1씩 증가하는 방식임. 그니깐 미리 value가 0인 word들을 넣어놓고 이후 word를 찾을 때 마다 value값을 1씩 증가시키는 거다.
  • 혹은 솔루션과 같은 방식으로 a란 변수 안에서 split()으로 쪼개는데 정규식에도 나와있다시피 'W'ord가 아닌 것이 한 번 혹은 한 번 이상이 나온 것을 기준으로 쪼갠다. 그 다음에 b라는 리스트 안에다가 list comprehension을 사용하여 banned에 해당되지 않는 단어들을 한 개씩 넣는다.

get()과 count()
이 함수는 딕셔너리에서 어떤 key의 value를 리턴한다. 안 넣으면 인자 없다고 오류남(None으로 처리한다는 뜻). count는 함수이름곧내. 마찬가지로 안 넣으면 인자 없다고 오류남.

max()
함수제목곧내

return이 뭘 하는지는 알겠는데 왜 max()에 get()과 count()에 괄호가 없나여?
왜냐하면 max()의 key로서 x.get 혹은 x.count로 통과시키면 메소드를 불러온 결과를 부르는 게 아니라, 메소드 그 자체를 불러오는 방식이기 때문이다. 즉, 어떠한 참조값을 해당 메소드에 통과시킴으로서 max()가 딕셔너리 (혹은 리스트)의 각각의 item들을 내부적으로 불러오는 거다. 따라서 실제 max()는 다음과 같은 방식으로 작동된다.

  1. 기능참조: x.get (혹은 x.count, 이하 get으로 통일)는 x의 get 메소드에 대한 참조가 됨.
  2. 내부적으로 불러오기: max 함수가 get 메소드를 불러옴으로써 x의 item들을 비교함.
  3. 최대치 찾기: max 함수는 x.get(key)을 통해 리턴된 값을 얻어서 어떤 게 최대치인지 결정.

끝.

profile
덕질기록용

0개의 댓글