본문 바로가기
Problem Solving/카카오 블라인드 기출

2019 - 매칭 점수

by Libi 2021. 8. 8.
반응형

https://programmers.co.kr/learn/courses/30/lessons/42893

 

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

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

programmers.co.kr

[ 문제풀이 ]

주어진 page에서 원하는 문자열을 파싱할 수 있는지를 물어보는 문제인 것 같다. 효율성이 없는 문제이기 때문에 그냥 전체 문자열에서 indexOf 메서드를 활용하여 원하는 문자열을 추출하면 해결할 수 있다.

어떻게 보면 문자열만 추출하면 되는 단순한 문제이지만 문제에 조건이 꽤 있기 때문에 꼼꼼하게 읽어야 한다. word는 영문자로만 구분한다는 것을 주의해라.

또한, url 링크는 meta tag 안에서 찾아야 한다. 처음에 그냥 "https:"를 기준으로 찾았는데 9번 테스트에서 자꾸 틀렸는데 아마 meta tag 밖에서 "https:" 형태의 url이 주어지는 테스트 케이스가 있는 것 같다.

import java.util.*;

class Solution {
	class WebPage implements Comparable<WebPage> {
		int index, outLink;
		double basicScore, outLinkScore, totalScore;
		String url;
		List<String> outLinkList;

		public WebPage(int index) {
			this.index = index;
			outLinkList = new ArrayList<>();
		}
        
        public int compareTo(WebPage o) {
            if (this.totalScore == o.totalScore) {
                return this.index - o.index;
            }
            return Double.compare(o.totalScore, this.totalScore);
        }
	}

	public int solution(String word, String[] pages) {
		WebPage[] wp = new WebPage[pages.length];
		word = word.toLowerCase(); //소문자로 통일

		Map<String, Integer> hm = new HashMap<>();
		
		for (int i = 0; i < pages.length; ++i) {
			pages[i] = pages[i].toLowerCase(); //소문자로 통일

			wp[i] = new WebPage(i);

			int metaStart = pages[i].indexOf("<meta property=");
            int urlStart = pages[i].indexOf("content=", metaStart);
            int urlEnd = pages[i].indexOf("/>", urlStart);
            
			wp[i].url = pages[i].substring(urlStart + 9, urlEnd - 1); //url 링크
			hm.put(wp[i].url, i); //외부 링크 계산하기 위해 HashMap에 url이 몇번째 wp인지 삽입

			int bodyStart = pages[i].indexOf("<body>", urlEnd);
			int bodyEnd = pages[i].indexOf("</body>", bodyStart);

			//body tag 안에서 word의 개수 찾음
			for (int j = bodyStart; j < bodyEnd - 1; ) {
				int wordStart = pages[i].indexOf(word, j);
				
				if (wordStart == -1) break; //없으면 종료

				//찾은 word의 양쪽이 영문자가 아니라면 기본 점수 1증가
				if (!Character.isAlphabetic(pages[i].charAt(wordStart - 1)) && !Character.isAlphabetic(pages[i].charAt(wordStart + word.length()))) {
					wp[i].basicScore++;
					j = wordStart + word.length();
					continue;
				}

				j = wordStart + word.length();
			}

			//body tag 안에서 외부 링크 개수 찾음
			for (int j = bodyStart; j < bodyEnd - 1; ) {
				int outLinkStart = pages[i].indexOf("<a href=", j);
				
				if (outLinkStart == -1) break; //없으면 종료

				int outLinkEnd = pages[i].indexOf(">", outLinkStart);
				
				//외부 링크 개수 1증가, 외부 링크 점수를 계산하기 위해 wp[i]의 리스트에 해당 url 삽입
				wp[i].outLink++;
				wp[i].outLinkList.add(pages[i].substring(outLinkStart + 9, outLinkEnd - 1));

				j = outLinkEnd;
			}
		}

		//모든 wp를 돌면서 외부 링크 점수 계산
		for (int i = 0; i < pages.length; ++i) {
			for (int j = 0; j < wp[i].outLinkList.size(); ++j) {
				String url = wp[i].outLinkList.get(j);
				
				if (hm.containsKey(url)) {
					int idx = hm.get(url);
					wp[idx].outLinkScore += wp[i].basicScore / wp[i].outLink;
				}
			}
		}

		for (int i = 0; i < pages.length; ++i) {
            wp[i].totalScore = wp[i].basicScore + wp[i].outLinkScore;
		}

        Arrays.sort(wp);
        
		return wp[0].index;
	}
}

 

 

반응형

'Problem Solving > 카카오 블라인드 기출' 카테고리의 다른 글

2020 - 문자열 압축  (0) 2021.08.08
2019 - 블록 게임  (0) 2021.08.08
2019 - 길 찾기 게임  (0) 2021.08.08
2019 - 무지의 먹방 라이브  (0) 2021.08.08
2019 - 후보키  (0) 2021.08.08

댓글