📍 문제 설명
https://school.programmers.co.kr/learn/courses/30/lessons/42892
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
💡 접근
문자열 파싱을 알맞게 잘 할 수 있는지 물어볼 수 있는 문제였다.
indexOf를 이용해서 각 태그들에 대해서 필요한 문자열을 추출한다.
1. <meta> 태그 안에 있는 웹페이지 URL -> <meta> 태그는 여러개일 수 있다.
2. <body> 태그 안에 있는 검색어
3. <body> 태그 안에 있는 <a href> 태그 URL
링크점수는 기본점수 / 외부링크 수 이므로 계산이 가능하고 매칭 점수에 더해지므로 따로 관리 안해도 된다.
페이지의 인덱스, 기본 점수, 외부 링크 수, 매칭 점수를 저장하면 원하는 답을 찾을 수 있다.
👩💻 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
class Main {
class Page implements Comparable<Page> {
private int idx;
private int searchScore, linkCnt;
double score;
public Page(int idx, int searchScore, int linkCnt, double score) {
this.idx = idx;
this.searchScore = searchScore;
this.linkCnt = linkCnt;
this.score = score;
}
@Override
public int compareTo(Page o) {
if(this.score == o.score) return this.idx - o.idx;
else if(this.score < o.score) return 1;
else return -1;
}
}
public int solution(String word, String[] pages) {
int answer = 0;
//기본점수, 외부 링크 수, 링크점수(다른 웹페이지 기본점수 % 외부 링크 수), 매칭점수(기본+링크)
//기본점수 -> body 태그 안에서 키워드를 찾자. (양 옆이 문자가 아니어야함)
//링크점수 -> body 태그 안에서 <a href= ~ 링크를 찾자. + 어디에 기록해놔야함
//링크 점수를 구하기 위해서 <url, index> 형식으로 저장
Map<String, Integer> map = new HashMap<>();
//각 웹페이지의 점수 관리
List<Page> pageList = new ArrayList<>();
word = word.toLowerCase();
//페이지 별로 구할 수 있는 점수 구하기
for(int i = 0; i < pages.length; i++) {
String s = pages[i] = pages[i].toLowerCase();
//meta 태그 내에 웹페이지 URL 구하기
int mid = 0, posl = 0, posr = 0;
//meta 태그가 여러 개 일 수 있다.
while (mid <= posl) {
posl = s.indexOf("<meta", posl + 1);
posr = s.indexOf(">", posl);
mid = s.lastIndexOf("https://", posr);
}
posr = s.indexOf("\"", mid);
String url = s.substring(mid, posr);
int wordLen = word.length();
//body 태그 내에 검색어 등장 횟수 구하기
posl = s.indexOf("<body>", posr);
int searchScore = 0;
for(int start = posl; ;) {
start = s.indexOf(word, start + 1);
if (start == -1) break;
//검색어의 앞뒤가 문자가 아니어야 검색어로 인정한다.
if (!Character.isLetter(s.charAt(start-1)) && !Character.isLetter(s.charAt(start+ wordLen))) {
searchScore += 1;
start += wordLen;
}
}
//body 태그 내에 하이퍼링크 갯수 구하기
int linkCnt = 0;
for(int start = posl; ;) {
start = s.indexOf("<a href", start + 1);
if (start == -1) break;
linkCnt++;
}
//링크 점수를 구하기 위해서 저장
map.put(url, i);
//페이지의 인덱스, 기본점수, 외부 링크 수 , 매칭점수 저장
pageList.add(new Page(i, searchScore, linkCnt, searchScore));
}
//위의 작업이 끝나고 map에 페이지들이 담겨야 list에 담긴 링크 점수를 갱신할 수 있음
//링크 점수 구하기
for(int i = 0; i < pages.length; i++) {
String s = pages[i];
for(int posl = 0, posr = 0; ;) {
posl = s.indexOf("<a href", posr);
//하이퍼링크 없으면 끝내기
if(posl == -1) break;
posl = s.indexOf("https://", posl);
posr = s.indexOf("\"", posl);
String linkurl = s.substring(posl, posr);
//map에 linkurl이 있는지 확인하고 점수 더해주기(기본 점수는 이미 더해놨으니 링크점수 누적해서 더하기)
Integer value = map.get(linkurl);
if(value != null) {
pageList.get(value).score += (double)pageList.get(i).searchScore / pageList.get(i).linkCnt;
}
}
}
Collections.sort(pageList);
answer = pageList.get(0).idx;
return answer;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
Main main = new Main();
String word = "blind";
String[] pages = {"<html lang=\"ko\" xml:lang=\"ko\" xmlns=\"http://www.w3.org/1999/xhtml\">\n" +
"<head>\n" +
" <meta charset=\"utf-8\">\n" +
" <meta property=\"og:url\" content=\"https://a.com\"/>\n" +
"</head>\n" +
"<body>\n" +
"Blind Lorem Blind ipsum dolor Blind test sit amet, consectetur adipiscing elit. \n" +
"<a href=\"https://b.com\"> Link to b </a>\n" +
"</body>\n" +
"</html>",
"<html lang=\"ko\" xml:lang=\"ko\" xmlns=\"http://www.w3.org/1999/xhtml\">\n" +
"<head>\n" +
" <meta charset=\"utf-8\">\n" +
" <meta property=\"og:url\" content=\"https://b.com\"/>\n" +
"</head>\n" +
"<body>\n" +
"Suspendisse potenti. Vivamus venenatis tellus non turpis bibendum, \n" +
"<a href=\"https://a.com\"> Link to a </a>\n" +
"blind sed congue urna varius. Suspendisse feugiat nisl ligula, quis malesuada felis hendrerit ut.\n" +
"<a href=\"https://c.com\"> Link to c </a>\n" +
"</body>\n" +
"</html>",
"<html lang=\"ko\" xml:lang=\"ko\" xmlns=\"http://www.w3.org/1999/xhtml\">\n" +
"<head>\n" +
" <meta charset=\"utf-8\">\n" +
" <meta property=\"og:url\" content=\"https://c.com\"/>\n" +
"</head>\n" +
"<body>\n" +
"Ut condimentum urna at felis sodales rutrum. Sed dapibus cursus diam, non interdum nulla tempor nec. Phasellus rutrum enim at orci consectetu blind\n" +
"<a href=\"https://a.com\"> Link to a </a>\n" +
"</body>\n" +
"</html>"};
main.solution(word, pages);
}
}
'Algorithm > programmers' 카테고리의 다른 글
[2022 카카오 블라인드]파괴되지 않은 건물★ (0) | 2022.07.15 |
---|---|
[2019 카카오 인턴십]징검다리 건너기 (0) | 2022.07.15 |
[2021 카카오 블라인드]광고 삽입 (0) | 2022.07.15 |
[2020 카카오 인턴십]경주로 건설 (0) | 2022.07.14 |
[2019 카카오 인턴십]불량 사용자★ (0) | 2022.07.14 |