본문 바로가기
대딩/프로그래머스풀이

[프로그래머스 lv3] 매칭 점수 풀이

by 경아ㅏ 2022. 9. 20.

해설

웬만한 문제는 c++로 푸는 것을 선호하지만, 문자열 + 정규표현식을 사용하면 편할 것 같아 파이썬을 사용했다.

 

1. page를 순회하면서 url과 link 뽑기, word 개수 세기

 

1) url과 links 뽑기

url의 경우 <meta property="og:url" content="https://careers.kakao.com/index" /> 형식이라고 했으므로, 다음과 같은 정규표현식을 사용한다. ()는 정규표현식에서 필요한 부분만 캡처하는 기능으로 .group(1)을 통해 해당 부분만 추출할 수 있다. 예를 들어, ...https://a.com ... 문자열에서 ()가 씌워진 a.com만 추출하는 것이다. 

 

url = re.search('<meta property=\"og:url\" content=\"https://([\S]+)\".*/>', page).group(1)

 

link의 경우 <a href="https://careers.kakao.com/index"> 형식이라고 했으므로, 다음과 같은 정규 표현식을 사용한다. ()내부의 [\S]+는 공백을 제외한 문자가 1개 이상 있다는 뜻이다. 원래 url에는 공백을 포함하면 안 되는데, 테스트 케이스에 공백을 포함한 url이 있다고 한다. 이런 주소들을 걸러주기 위해 [\S]+로 정상적인 링크만 추출한다.

 

links = re.findall('<a href=\"https://([\S]+)\">', page)

 

2) word 개수 뽑기

[a-z]+는 알파벳으로 이루어진 한덩이의 단어를 추출한다. page에서 모든 단어를 추출한 후 word와 같으면 cnt를 1 증가시킨다.

 

cnt = 0
for w in re.findall('[a-z]+', page):
    if w == word:
        cnt += 1

 

위의 정보들로 기본 점수, 외부 링크 수를 쉽게 구할 수 있다.

 

 

 

2. 링크점수, 매칭점수 구하기

 

1) i번째 페이지가 페이지 p를 포함하고 있을 때, (i번째 페이지의 기본점수 / i번째 페이지의 외부 링크 수)를 페이지 p의 링크 점수에 더한다. 주의할 것은 i번째 페이지의 외부 링크 수가 0이 아니어야 하고(나누는 수가 0이면 안됨), 페이지 p가 주소 목록에 있어야 한다. 

 

#링크점수 구하기
for i in range(len(li)):
    if nl[i] == 0: continue
    val = sb[i]/nl[i] #기본점수/외부링크수
    for p in li[i]:
        if (p in ad):
            idx = ad.index(p)
            sl[idx] += val

 

 2) 기본점수와 링크 점수를 더하여 각 페이지들의 매칭점수를 구한다. 이때, 최초로 등장하는 최댓값의 인덱스를 구하여 리턴하면 정답이다.

 

#매칭점수 구하기
mx = -1
mxidx = -1
for i in range(len(sm)):
    sm[i] = sb[i] + sl[i]
    if sm[i] > mx:
        mx = sm[i]
        mxidx = i

 

 

전체 코드

import re

ad = [] #본인 주소
li = [] #외부 링크

sb = [] #기본 점수
nl = [] #외부 링크 수
sl = [] #링크 점수
sm = [] #매칭 점수

def solution(word, pages):
    
    word = word.lower()
    
    #파싱
    for page in pages:
        
        page = page.lower()

        url = re.search('<meta property=\"og:url\" content=\"https://([\S]+)\".*/>', page).group(1)
        links = re.findall('<a href=\"https://([\S]+)\">', page)
        
        cnt = 0
        for w in re.findall('[a-z]+', page):
            if w == word:
                cnt += 1
        
        ad.append(url)
        sb.append(cnt)
        sl.append(0)
        sm.append(0)
        
        if links is None:
            li.append([])
            nl.append(0)
        else: 
            li.append(links)
            nl.append(len(links))
            

    #링크점수 구하기
    for i in range(len(li)):
        if nl[i] == 0: continue
        val = sb[i]/nl[i] #기본점수/외부링크수
        for p in li[i]:
            if (p in ad):
                idx = ad.index(p)
                sl[idx] += val
    
    #매칭점수 구하기
    mx = -1
    mxidx = -1
    for i in range(len(sm)):
        sm[i] = sb[i] + sl[i]
        if sm[i] > mx:
            mx = sm[i]
            mxidx = i
            
    return mxidx

 

 

댓글