해설
웬만한 문제는 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
'대딩 > 프로그래머스풀이' 카테고리의 다른 글
[프로그래머스 lv3] 선입 선출 스케줄링 풀이 (0) | 2022.09.22 |
---|---|
[프로그래머스 lv3] 아이템 줍기 풀이 (0) | 2022.09.21 |
[프로그래머스 lv3] 모두 0으로 만들기 풀이 (0) | 2022.09.20 |
[프로그래머스 lv3] 블록 이동하기 풀이 (0) | 2022.09.19 |
[프로그래머스 lv3] 광고 삽입 풀이 (0) | 2022.09.19 |
댓글