728x90
[프로그래머스] 2019 KAKAO BLIND RECRUITMENT 매칭 점수 : https://programmers.co.kr/learn/courses/30/lessons/42893
2019 카카오 공채의 6번째 문제 매칭 점수다.
이번 코테에서 가장 어려웠던 문제인 것 같다. 내가 문자열에 많이 약하다는 것을 알게 된 계기가 되었다.
문자열 파싱과 정규표현식 응용하는 것에 대해 공부를 해야겠다.
문제가 굉장히 길긴 하지만, 이해하기 크게 어렵진 않다.
웹페이지의 html을 입력받으면 기본점수, 외부 링크 수, 링크 점수, 매칭점수를 구하면 된다.
이번 문제에서 구현해야 하는 로직은 다음과 같다. 아래의 순서대로 실행을 하면 된다.
- html에서 해당 웹페이지의 url 추출하기. (findUrl 함수)
- 검색어(word)가 등장하는 횟수를 체크해서 기본 점수 계산하기. (setDefaultScore 함수)
- 한 웹페이지의 외부 링크 수 계산하기. (setLinkCount 함수)
- 웹페이지의 링크 점수 계산하기. (setLinkScore 함수)
링크 점수를 계산할 때 외부 웹페이지의 url을 바로 찾아야 해서 HashMap을 사용했다.
위의 로직을 모두 수행하면 각각의 웹페이지의 링크 점수가 나온다.
기본점수와 링크 점수의 합으로 정렬을 한 뒤, 가장 큰 값의 웹페이지의 index를 구하면 된다.
처음엔 정규표현식이 익숙지 않아 사용하지 않고 문자열 파싱을 했는데 굉장히 번거롭고 코드가 난잡해졌다.
도저히 이렇게는 안될 것 같아 정규표현식을 공부한 뒤, 다시 처음부터 구현했다.
문자열 파싱 관련해서 새로운 개념을 많이 공부한 듯해서 풀길 잘했다는 생각이 든다.
당분간은 백준에서 문자열 파싱과 정규표현식 문제를 찾아 풀어봐야겠다.
총 걸린 시간 : 3시간 이상
난이도 : ★★★★★
코드
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Solution {
private HashMap<String, Page> map = new HashMap<>();
public int solution(String word, String[] pages) {
int idx = 0;
for (String html : pages) {
Page page = new Page(idx++, html.toLowerCase());
page.setDefaultScore(word.toLowerCase());
page.setLinkCount();
map.put(page.url, page);
}
for (Page page : map.values()) {
page.setLinkScore();
}
ArrayList<Page> list = new ArrayList(map.values());
Collections.sort(list);
return list.get(0).idx;
}
class Page implements Comparable<Page> {
int idx;
int defaultScore = 0;
int linkCount = 0;
double linkScore = 0;
String html, url;
Page(int idx, String html) {
this.idx = idx;
this.html = html;
findUrl();
}
private void findUrl() {
Pattern pattern = Pattern.compile("<meta property=\"og:url\" content=\"https://(.+?)\"/>");
Matcher matcher = pattern.matcher(html);
while (matcher.find()) {
url = matcher.group(1);
}
}
public void setDefaultScore(String word) {
int idx = html.indexOf(word);
while (idx != -1) {
char pre = html.charAt(idx - 1);
char post = html.charAt(idx + word.length());
if (!Character.isLowerCase(pre) && !Character.isLowerCase(post)) {
defaultScore++;
}
idx = html.indexOf(word, idx + 1);
}
}
public void setLinkCount() {
int idx = html.indexOf("<a href=");
while (idx != -1) {
linkCount++;
idx = html.indexOf("<a href=", idx + 1);
}
}
public void setLinkScore() {
Pattern pattern = Pattern.compile("<a href=\"https://(.+?)\">");
Matcher matcher = pattern.matcher(html);
while (matcher.find()) {
String externalUrl = matcher.group(1);
if (map.containsKey(externalUrl)) {
map.get(externalUrl).linkScore += (double) defaultScore / linkCount;
}
}
}
@Override
public int compareTo(Page other) {
double a = (double) this.defaultScore + this.linkScore;
double b = (double) other.defaultScore + other.linkScore;
return Double.compare(b, a);
}
}
}
728x90
'Algorithm > Programmers' 카테고리의 다른 글
[프로그래머스] 2019 KAKAO BLIND RECRUITMENT 블록 게임 (Java) (0) | 2020.03.06 |
---|---|
[프로그래머스] 2019 KAKAO BLIND RECRUITMENT 길 찾기 게임 (Java) (0) | 2020.03.06 |
[프로그래머스] 2019 KAKAO BLIND RECRUITMENT 무지의 먹방 라이브 (Java) (0) | 2020.03.06 |
[프로그래머스] 2019 KAKAO BLIND RECRUITMENT 후보키 (Java) (0) | 2020.03.06 |
[프로그래머스] 2020 KAKAO BLIND RECRUITMENT 블록 이동하기 (Java) (1) | 2020.03.01 |