html 문자열 파싱 문제이다. 웹 페이지들의 매칭 점수를 구한 뒤 가장 큰 매칭 점수를 가진 웹 페이지 인덱스를 출력한다. 매칭 점수는 기본 점수와 링크 점수의 합으로 계산하며, 기본 점수는 해당 웹 페이지의 텍스트 중 검색어가 등장하는 횟수이다. 링크 점수는 해당 웹페이지로 링크가 걸린 다른 웹페이지의 기본 점수 / 외부 링크 수의 총합으로 구할 수 있다.
기본 점수는 메시지 body 부분을 잘라낸 후 body에서 word가 몇 개 있는지 세어 확인할 수 있다.
링크 점수는 각 페이지를 순회하며 해당 페이지에서 외부로 링크된 모든 페이지를 확인하면서, 외부 링크된 각 페이지에 현재 페이지의 기본 점수를 외부 링크 수로 나눈 값을 더하여 구할 수 있다.
for (int i = 0; i < pages.length; ++i) {
String page = pages[i];
String baseUrl = getBaseUrl(page);
for (var link : externalLinks[i]) {
if (ps.containsKey(link)) {
int linkIndex = ps.get(link);
linkScores[linkIndex] += (double) basicScores[i] / externalLinks[i].size();
}
}
}
String getBaseUrl(String page) {
String find = "<meta property=\"og:url\" content=\"";
int st = page.indexOf(find) + find.length();
int en = page.indexOf("\"", st);
return page.substring(st, en);
}
List<String> getExternalLinks(String page) {
List<String> links = new ArrayList<>();
int pos = page.indexOf("<a href=\"");
while (pos != -1) {
int start = pos + "<a href=\"".length();
int end = page.indexOf("\"", start);
links.add(page.substring(start, end));
pos = page.indexOf("<a href=\"", end);
}
return links;
}
int getBasicScore(String word, String page) {
String lowerPage = page.toLowerCase();
String body = lowerPage.substring(lowerPage.indexOf("<body>") + 7, lowerPage.indexOf("</body>"));
int score = 0;
String[] words = body.split("[^a-zA-Z]");
for (var w : words) {
if (w.equals(word)) {
score++;
}
}
return score;
}
double[] totalScores = new double[pages.length];
for (int i = 0; i < pages.length; ++i) {
totalScores[i] = basicScores[i] + linkScores[i];
}
int ans = 0;
for (int i = 1; i < pages.length; ++i) {
if (totalScores[i] > totalScores[ans]) {
ans = i;
}
}
return ans;
import java.util.*;
class Solution {
public int solution(String word, String[] pages) {
word = word.toLowerCase();
Map<String, Integer> ps = new HashMap<>(); // url, index
List<String>[] externalLinks = new ArrayList[pages.length];
int[] basicScores = new int[pages.length];
double[] linkScores = new double[pages.length];
for (int i = 0; i < pages.length; ++i) {
externalLinks[i] = new ArrayList<>();
String baseUrl = getBaseUrl(pages[i]);
ps.put(baseUrl, i);
basicScores[i] = getBasicScore(word, pages[i]);
externalLinks[i] = getExternalLinks(pages[i]);
}
for (int i = 0; i < pages.length; ++i) {
String page = pages[i];
String baseUrl = getBaseUrl(page);
for (var link : externalLinks[i]) {
if (ps.containsKey(link)) {
int linkIndex = ps.get(link);
linkScores[linkIndex] += (double) basicScores[i] / externalLinks[i].size();
}
}
}
double[] totalScores = new double[pages.length];
for (int i = 0; i < pages.length; ++i) {
totalScores[i] = basicScores[i] + linkScores[i];
}
int ans = 0;
for (int i = 1; i < pages.length; ++i) {
if (totalScores[i] > totalScores[ans]) {
ans = i;
}
}
return ans;
}
String getBaseUrl(String page) {
String find = "<meta property=\"og:url\" content=\"";
int st = page.indexOf(find) + find.length();
int en = page.indexOf("\"", st);
return page.substring(st, en);
}
int getBasicScore(String word, String page) {
String lowerPage = page.toLowerCase();
String body = lowerPage.substring(lowerPage.indexOf("<body>") + 7, lowerPage.indexOf("</body>"));
int score = 0;
String[] words = body.split("[^a-zA-Z]");
for (var w : words) {
if (w.equals(word)) {
score++;
}
}
return score;
}
List<String> getExternalLinks(String page) {
List<String> links = new ArrayList<>();
int pos = page.indexOf("<a href=\"");
while (pos != -1) {
int start = pos + "<a href=\"".length();
int end = page.indexOf("\"", start);
links.add(page.substring(start, end));
pos = page.indexOf("<a href=\"", end);
}
return links;
}
}