본문 바로가기

알고리즘 풀이/프로그래머스

[프로그래머스] 매칭점수 / 2019 KAKAO BLIND RECRUITMENT - JAVA

🔗 문제 링크

[프로그래머스] 매칭점수 / 2019 KAKAO BLIND RECRUITMENT

 

코딩테스트 연습 - 매칭 점수

매칭 점수 프렌즈 대학교 조교였던 제이지는 허드렛일만 시키는 네오 학과장님의 마수에서 벗어나, 카카오에 입사하게 되었다. 평소에 관심있어하던 검색에 마침 결원이 발생하여, 검색개발팀

programmers.co.kr

 

📝 풀이 과정

다소 복잡하지만 문제에 주어진 그대로만 구현하면 되는 문제다. 자바에서 정규식 처리를 쉽게 할 수 있도록 만든 Pattern과 Matcher를 사용하여 구현하였다. (참고: [Java] Pattern, Matcher Class 사용법과 메소드 정리)

 

Pattern urlPattern = Pattern.compile("<head>[\\s\\S]*<meta[^>]*content=\"(?<url>[^\"]*)\"");
Pattern linkPattern = Pattern.compile("<a href=\"(?<link>[^\"]*)\"", Pattern.MULTILINE);

url은 <head>안에 있는 <meta> 태그 에 존재하는 content attribute에 존재한다고 했기 때문에 위와같은 정규식으로 구성하였다. 
웹페이지에 존재하는 외부 링크들을 가져오기 위한 linkPattern도 만들어주었다.

 

현재의 웹페이지가 참조하고 있는 외부링크들을 저장하기 위한 Map<String, Set>을 생성해 참조된 웹페이지를 Key로 넣어주고, 현재 웹페이지를 Set에 add해주었다.

 

getScore()함수를 구현해 외부링크와 검색어의 개수를 파악해 점수를 반환하도록하고, 이를 사용해 compareTo() 메소드를 오버라이드하여 정렬하여 답을 반환해주었다.

 

💻 코드

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

class Solution {
    Map<String, Set<WebPage>> refer = new HashMap<>();

    Pattern urlPattern = Pattern.compile("<head>[\\s\\S]*<meta[^>]*content=\"(?<url>[^\"]*)\"");
    Pattern linkPattern = Pattern.compile("<a href=\"(?<link>[^\"]*)\"", Pattern.MULTILINE);
    String word;

    public int solution(String word, String[] pages) {
        this.word = word.toLowerCase();

        List<WebPage> list = IntStream.range(0, pages.length)
                .mapToObj(i -> new WebPage(i, pages[i].toLowerCase())).sorted().collect(Collectors.toList());

        return list.get(0).idx;
    }

    class WebPage implements Comparable<WebPage> {
        int idx, score, linkCnt;
        String url;
        double linkScore;

        WebPage(int idx, String page) {
            this.idx = idx;
            Matcher urlMatcher = urlPattern.matcher(page);
            Matcher linkMatcher = linkPattern.matcher(page);

            urlMatcher.find(); 
            url = urlMatcher.group("url");

            while (linkMatcher.find()) {
                linkCnt++;
                refer.computeIfAbsent(linkMatcher.group("link"), s -> new HashSet<>()).add(this);
            }

            for (String s : page.split("[^a-z]+")) {
                if (word.equals(s)) score++;
            }

            linkScore = (double) score / linkCnt;
        }

        double getScore() {
            return score + (refer.containsKey(this.url) ? refer.get(this.url).stream().mapToDouble(o -> o.linkScore).sum() : 0);
        }

        @Override
        public int compareTo(WebPage o) {
            return o.getScore() != this.getScore() ? Double.compare(o.getScore(), this.getScore()) : Integer.compare(this.idx, o.idx);
        }
    }
}