카카오 - 매칭 점수

아따맘마·2021년 1월 21일
0

알고리즘 - 카카오

목록 보기
16/19

문제

프로그래머스 사이트

풀이

틀린 코드

또 어떤 예외처리를 못한건지...

#include <string>
#include <vector>
#include <map>
#include <iostream>
#include <algorithm>

using namespace std;
vector<vector<string>> link;

string ft_site(string pages, int j) {
	int length = 0;
	string tmp;
	int i = j;

	while (pages[++i] != '"') {
		length++;
	}
	tmp = pages.substr(j, length+1);

	return tmp;
}

string ft_check_link(string pages, int i) {
	int length = 0;
	int j = i;
	string tmp;

	while (pages[++j] != '"') {
		length++;
	}
	tmp = pages.substr(i, length + 1);
	return tmp;
}

float ft_check_word(string pages, int j, string word)
{
	int i = j;
	float score = 0;
	vector<string> tmp;

	while (pages.substr(i, 7) != "</body>") {
		if (pages.substr(i, 5) == "href=") {
			i += 6;
			tmp.push_back(ft_check_link(pages, i));
		}
		pages[i] = tolower(pages[i]);
		i++;
	}
	for (int k = j; k < i; k++) {
		if ((pages.substr(k, word.length()) == word) && !(pages[k + word.length() + 1] >= 'a' && pages[k + word.length() + 1] <= 'z') && 
			(!(pages[k-1] >= 'a' && pages[k-1] <= 'z'))) {
			score++;
		}
	}
	link.push_back(tmp);
	return score;
}

bool ft_compare(pair<int, float> a, pair<int, float> b)
{
	if (a.second == b.second)
		return a.first < b.first;
	return a.second > b.second;
}


int solution(string word, vector<string> pages) {
	int answer = 0;
	map<int, string> m;
	vector<pair<int, float>> score;
	map<int, float> sum;

	for (int i = 0; i < word.length(); i++)
		word[i] = tolower(word[i]);

	for (int i = 0; i < pages.size(); i++) {
		for (int j = 0; j < pages[i].length(); j++) {
			if (pages[i].substr(j, 8) == "content=") {
				j += 9;
				m[i] = ft_site(pages[i], j);
			}
			else if (pages[i].substr(j, 6) == "<body>")
			{
				j += 7;
				score.push_back(make_pair(i, ft_check_word(pages[i], j, word)));
			}
		}
	}

	for (int i = 0; i < pages.size(); i++)
	{
		sum[i] = score[i].second;
		for (int j = 0; j < pages.size(); j++) {
			for (int k = 0; k < link[j].size(); k++)
				if (link[j][k] == m[i])
					sum[i] += (score[j].second / link[j].size());
		}
	}

	vector<pair<int, float>> vec(sum.begin(), sum.end());
	stable_sort(vec.begin(), vec.end(), ft_compare);
	
	answer = vec[0].first;
	return answer;
}

int main()
{
	vector<string> s = { "<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://careers.kakao.com/interview/list\"/>\n</head>  \n<body>\n<a href=\"https://programmers.co.kr/learn/courses/4673\"></a>#!MuziMuzi!)jayg07con&&\n\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://www.kakaocorp.com\"/>\n</head>  \n<body>\ncon%\tmuzI92apeach&2<a href=\"https://hashcode.co.kr/tos\"></a>\n\n\t^\n</body>\n</html>" };
	int ans = solution("blind", s);
	cout << ans;
}

정답 처리

이것도 하다가 안되서 구글링해봤다. 여기서 배운것은 find, string::npos, 그리고 반복자 처리에서 사용하는 find정도이다. 위에 내가 푼 틀린코드는 계속 substr로 문자열을 추출해서 찾아보는 쌩 노가다식이기도 하고, 코드 상태가 매우 드럽고 지저분하고 가져다 버려버리고 싶어보이는 코드이다.
이번 정답처리한것도 구글링해서 풀었지만 깔끔하게 보이고 싶어 다 함수처리해주고, 전역변수를 사용해서 중간중간 함수로 넘어갈 때 다시 처음부터 검색하는 것이 아니라 전역변수로 지정한 부분부터 검색하게 수정을 해보았다.
그리고 깨달은것 하나!
무조건 사용할 변수가 많으면 구조체 처리해라...
틀린 코드는 보면 map을 두개... 벡터도 안에 pair을 써서 총 3개
이렇다보니 코드를 짤 때 헷갈려지더라..

#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <iostream>
using namespace std;

int world_left;

typedef struct Page {
	int idx;
	int basic, link;
	double score;
} page;

bool ft_compare(page& a, page& b) {
	if (a.score == b.score)
		return a.idx < b.idx;
	return a.score > b.score;
}

string ft_url(string str) {
	int mid = 0, left = 0, right;

	while (mid <= left) {
		left = str.find("<meta", left + 1);
		right = str.find(">", left);
		mid = str.rfind("https://", right);
	}
	right = str.find("\"", mid);

	string tmp = str.substr(mid, right - mid);
	world_left = left;

	return tmp;
}

int ft_check_word(string str, string word, int size)
{
	int score = 0;
	int left = str.find("<body>", world_left);
	int start = left;

	for (int i = start ; ;) {
		start = str.find(word, start + 1);
		if (start == string::npos)
			break;
		else
		{
			if (!isalpha(str[start - 1]) && !isalpha(str[start + size]))
			{
				score++;
				start += size;
			}
		}
	}

	return score;
}

int ft_check_link(string str) {
	int left = world_left;
	int start = left;
	int link = 0;

	while (1) {
		start = str.find("<a href", start + 1);
		if (start == string::npos)
			break;
		link++;
	}
	return link;
}

int solution(string word, vector<string> pages) {
	int w_size = word.length();
	map <string, int> url;
	vector<page> pagelist;
	int answer = 0;

	transform(word.begin(), word.end(), word.begin(), ::tolower);

	for (int i = 0; i < pages.size(); i++) {
		string& s = pages[i];
		world_left = 0;
		transform(s.begin(), s.end(), s.begin(), ::tolower);

		string pages_url = ft_url(pages[i]);

		int score = ft_check_word(pages[i], word, w_size);

		int count_link = ft_check_link(pages[i]);

		url[pages_url] = i;
		pagelist.push_back({ i, score, count_link, (double)score });
	}
	//for (auto x : pagelist) {
	//	cout << x.idx << ' ' << x.basic << ' ' << x.score << ' ' << x.link << '\n';
	//}

	for (int i = 0; i < pages.size();i++) {
		string str = pages[i];
		int left = 0, right = 0, mid;
		
		while (1) {
			left = str.find("<a href=", right);
			if (left == string::npos)
				break;
			right = str.find(">", left);
			mid = str.rfind("https://", right);
			right = str.find("\"", mid);
			string tmp = str.substr(mid, right - mid);
			
			map<string, int>::iterator it = url.find(tmp);
			if (it != url.end()) {
				pagelist[it->second].score += ((double)pagelist[i].basic / pagelist[i].link);
			}
		}
	}
	sort(pagelist.begin(), pagelist.end(), ft_compare);
	answer = pagelist[0].idx;

	return answer;
}

int main()
{
	vector<string> s = { "<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>\nBlind 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>\nSuspendisse potenti. Vivamus venenatis tellus non turpis bibendum, \n<a href=\"https://a.com\"> Link to a </a>\nblind 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>\nUt 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>" };
	int n = solution("blind", s);
	cout << n;
}
profile
늦게 출발했지만 꾸준히 달려서 도착지점에 무사히 도달하자

0개의 댓글