이번 문제는 매칭 점수 문제이다.
한 웹페이지에 대하여 기본점수, 외부 링크 수, 링크점수, 매칭점수가 존재한다.
기본점수는 검색어가 등장하는 횟수를 의미한다(대소문자 무시).
외부 링크 수 는 해당 페이지에 다른 외부 페이지로 연결된 링크의 개수이다.
링크점수는 해당 페이지로 링크가 걸린 다른 웹페이지의 기본점수 / 외부 링크 수의 총합니다. (나누기이다!!)
매칭점수는 기본점수 + 링크점수 이다.
아... 벌써부터 설명에 머리가 아파온다.
위 예시를 같이 살펴보자.
먼저 검색어는 'hi' 이다. 대소문자를 무시하기 때문에 A, B, C의 기본점수는 1점,4점,9점이 된다.
외부 링크 수는 1개, 2개, 3개이고 링크점수는
A = B (기본점수 4점 / 외부 링크 수 2 = 2점) + C(기본점수 9 / 외부 링크 수 3 = 3점) = 5점이 된다.
B = 0 점, C = 0점이다. (외부에서 B,C에 연결된 페이지가 존재하지 않기 때문)
따라서 A,B,C 의 매칭 점수는 6점, 4점, 9점이며, 이때 반환해야할 가장 높은 점수의 index는 2가 된다.
제한사항도 굉장히 설명이 길다.
먼저 전달받은 웹페이지들의 형태를 잘 살펴보아야 한다.
HTML 형식의 웹페이지가 문자열 형태로 전달 된다. 따라서 웹페이지의 url 은 http:// 로 시작한다.
외부 링크의 경우 <a href> 태그로 작성되어 있다.
검색어는 대소문자를 무시하고, 단어 단위로 완전히 일치할 경우만 기본 점수에 반영한다.(띄워쓰기 구분)
점수가 동일한 경우라면, index 번호가 가장 작은 것을 반환한다.
이제 예제를 통해 어떤 형태인지 확인해 보자.
입출력 예제 1을 형식에 맞춰 다시 배열한 모습이고, 검색어는 blind 이다.
사실 설명을 몇 번 더 읽느니, 차라리 예제를 보고 이해하는게 더 빠를지도 모른다.
각 페이지의 주소는 a.com / b.com / c.com 이다.
a.com 의 기본점수는 3, 외부 링크 수는 1개
b.com 의 기본점수는 1, 외부 링크 수는 2개
c.com 의 기본점수는 1, 외부 링크수는 1개이다.
링크점수는 a.com 의 경우 b.com (0.5점) + c.com(1점) = 1.5점
b.com 은 a.com(3점)
c.com 은 b.com(0.5점)이다.
따라서 각 페이지의 점수는 4.5점, 4점, 1.5점이며 index 0 을 리턴하면 된다.
해당 문제를 풀기위해 정규식 표현을 다시 공부하였다.
split() 또는 replace를 활용해 보려고도 했었으나, 특정 테케에서 자꾸 막히는 걸로 봐서는 정규식 사용이 강제되는듯 했다.
먼저 전달받은 word를 lower() 함수로 전부 소문자로 치환하여 준다.
그리고 pages 를 반복하여 돌게 되는데, 이때 각 페이지 역시 소문자로 치환하고 시작하였다.
b_score 는 해당 페이지의 기본점수가 된다.
현제 페이지의 주소를 알기 위해서는 re.search()를 통해 탐색하였다. 문제 조건에 의해 meta 태그로 주어지기에 그대로 똑같이 입력해주고, 사용할 주소 부분만 () 로 그룹화 해주었다.
다음 필요한건 기본점수이다.
re.findall()을 사용하는데, 역시 찾을 문자열은 [a-z] 이며, + 를 입력해 줌으로써 연속된 문자열을 찾게 된다. 여기서 findall()을 사용한 이유는 문제에서 HTML 내의 모든 문자와 word 가 일치하는지 확인하라고 하였기 때문이다. 따라서 찾게되는 find 문자열은 오직 a-z 로만 이루어진 문자열이 된다. (불필요하게 split()을 통해 나누어 주지 않아도 된다)
to_link 는 해당 페이지에서 외부로 나가는 링크를 찾아 저장하게 된다.
zero division error 를 막기위해 조건문을 통해 해당 페이지의 주소, 기본점수, 링크점수, 외부링크 순서로 temp 에 저장한다.
그리고 다시 해당 temp 를 이중 반복문으로 탐색하고, 만약 다른 페이지에 해당 주소(temp[i][0]) 이 존재 한다면 다른 페이지의 링크점수를 추가하여 answer에는 (매칭점수, index) 배열에 저장하게 된다.
최종적으로 x[0] (매칭점수) 기준으로 오름차순 정렬한 다음, answer[0][1] 을 반환해 주면 된다.
솔직하게, 설명만 좀 친절했어도 그리 어려운 문제는 아니였다.
아직도 왜 split()과 replace를 통해 풀이가 안되었는지, 테케를 보고 싶다...
'프로그래머스 퀴즈(Python) > level 3' 카테고리의 다른 글
23.03.07 파이썬 코딩 퀴즈#186 등굣길(프로그래머스 스쿨) (0) | 2023.03.07 |
---|---|
23.03.07 파이썬 코딩 퀴즈#185 N으로 표현(프로그래머스 스쿨) (0) | 2023.03.07 |
23.03.06 파이썬 코딩 퀴즈#183 길 찾기 게임(프로그래머스 스쿨) (0) | 2023.03.06 |
23.03.03 파이썬 코딩 퀴즈#182 단속카메라(프로그래머스 스쿨) (0) | 2023.03.03 |
23.03.02 파이썬 코딩 퀴즈#181 섬 연결하기(프로그래머스 스쿨) (0) | 2023.03.02 |