문제
- 매칭점수가 가장 높은 웹페이지 구하기 (여러 개라면 그 중 번호가 가장 작은 것)
- 기본점수 = 검색어가 등장하는 횟수 (대소문자 무사)
외부 링크 수 = 다른 외부 페이지로 연결된 링크 개수
링크점수 = (해당 웹페이지로 링크가 걸린 다른 웹페이지의 기본점수 / 외부 링크 수)의 총합
매칭점수 = 기본점수 + 링크점수
- 1 <= 페이지 개수 <= 20
- 1 <= 페이지별 문자열 길이 <= 1500
풀이
- 크게 4가지 작업으로 나눌 수 있다.
- 1) 해당 페이지의 url 찾기
re 모듈을 사용해 찾은 뒤, 해당 url의 인덱스를 저장한다.
- 2) body 부분에서 기본 점수 계산하기
re 모듈을 사용해 body 부분만 추출하고, 특수문자를 모두 공백으로 처리한 뒤, 매칭되는 단어 개수를 센다.
- 3) body 부분에서 외부 링크 추출하기
re 모듈을 사용해 외부 링크의 포맷에 맞게 찾아 저장한다.
- 4) 링크 점수 계산하기
*** A가 B라는 링크를 가지고 있으면, B에 (A 기본점수 / A 링크 개수)를 더해줘야 한다!
import re
from collections import defaultdict
def calc_basic(page, word) :
body = page.split("<body>\n")[1].split("</body>")[0] # body 부분만 추출
body = re.sub(r"[^a-zA-Z]", " ", body) # 알파벳만 남기기
body = re.sub(' +', ' ', body).lower() # 공백 1개로 줄이기
# 공백 기준 매칭되는 단어 개수 리턴
return len([w for w in body.split() if w == word])
def solution(word, pages):
word = word.lower()
# url 별 (인덱스, 기본점수, 외부링크, 링크 점수)
matching_score = defaultdict(list)
for i, page in enumerate(pages) :
# url 찾기
url = re.findall('<meta property="og:url" content="(https://\S+)"/>', page)[0]
matching_score[url].append(i)
# 1) 기본점수 계산
matching_score[url].append(calc_basic(page, word))
# 2) 외부 링크 찾기
links = []
for link in re.findall('<a href="(https://\S+)">', page) :
links.append(link)
matching_score[url].append(links)
matching_score[url].append(0) # 링크 점수 추가
# 3) 링크점수 계산
for url in matching_score :
_, basic, links, _ = matching_score[url]
cnt = len(links)
for link in links :
if link in matching_score : # 존재하는 외부링크인 경우
matching_score[link][-1] += basic / cnt
# 매칭 점수 : 기본 점수 + 링크 점수
answer = sorted([(matching_score[url][0], matching_score[url][1]+matching_score[url][3]) for url in matching_score], key=lambda x: (-x[1], x[0]))
return answer[0][0]