-
프로그래머스 - 매칭 점수 [C++]문제 풀이/프로그래머스 2024. 3. 2. 22:33반응형
이 문제는 문자열, 구현 문제이다.
주요 포인트는 대소문자 구별 X, 알파벳을 제외한 모든 문자가 구분자가 되는 단어들 파싱, 내 링크 및 외부 링크 찾기이다.
대소문자 구별을 하지 않는 방법은 전부 대문자나 소문자로 바꿔놓는 것이다. 이는 간단하게 구현할 수 있다.
알파벳을 제외한 모든 문자가 구분자가 되는 단어들을 파싱하기 위해 for문을 돌리면서 'a' <= c && c <= 'z' 를 체크하고, 아닌 경우에는 지금까지 쌓여있던 단어를 리턴 벡터에 저장하는 방식으로 구현했다.
내 링크 및 외부 링크 찾기는 kmp 알고리즘을 사용하여 속도를 높였다. 여기서 주의할 점은 단순히 "http://" 를 찾으면 오답이 나오게 되고, 태그까지 정확히 걸어서 "<a href=\"" 를 검색하게 만들어야 한다. 이 또한 kmp 알고리즘을 외우고만 있으면 쉽게 구현할 수 있다.
위 세 가지를 제외한 부수적인 부분들은 쉽게 구현할 수 있고, 이 요구사항들을 구현만 하면 정답이 나오게 된다.
#include <string> #include <vector> #include <iostream> #include <sstream> #include <map> using namespace std; char toLower(char c) { if ('A' <= c && c <= 'Z') { return c + ('a' - 'A'); } else { return c; } } vector<string> split(string input) { vector<string> result; string temp = ""; for (char c : input) { if ('a' <= c && c <= 'z') { temp += c; } else { if (!temp.empty()) { result.push_back(temp); } temp = ""; } } if (!temp.empty()) { result.push_back(temp); } return result; } vector<int> getPi(string comp) { int m = comp.size(); vector<int> pi(m, 0); int start = 1; int matched = 0; while (start + matched < m) { if (comp[start + matched] == comp[matched]) { matched++; pi[start + matched - 1] = matched; } else { if (matched == 0) { start++; } else { start += matched - pi[matched - 1]; matched = pi[matched - 1]; } } } return pi; } vector<int> kmp(string all, string comp) { int n = all.size(); int m = comp.size(); vector<int> pi = getPi(comp); vector<int> result; int start = 0; int matched = 0; while (start <= n - m) { if (matched < m && all[start + matched] == comp[matched]) { matched++; if (matched == m) { result.push_back(start); } } else { if (matched == 0) { start++; } else { start += matched - pi[matched - 1]; matched = pi[matched - 1]; } } } return result; } string getUrl(int index, string& page) { string result = ""; for (int i = index; page[i] != '\"'; i++) { result += page[i]; } return result; } struct Node { string url = ""; int base = 0; int outer = 0; double link = 0; double matching = 0; }; map<string, int> urlToIndex; map<string, vector<int>> links; vector<Node> nodes; string getMyUrl(string page) { vector<int> urlIndex = kmp(page, "<meta property=\"og:url\" content=\""); string myUrl = getUrl(urlIndex[0] + 33, page); return myUrl; } int calculateBase(string page, string word) { vector<string> words = split(page); int base = 0; for (string& w : words) { if (w == word) { base++; } } return base; } int calculateOuter(string page, int me) { vector<int> urlIndex = kmp(page, "<a href=\""); int outer = urlIndex.size(); for (int i = 0; i < urlIndex.size(); i++) { string url = getUrl(urlIndex[i] + 9, page); links[url].push_back(me); } return outer; } void allLower(string& word) { for (int i = 0; i < word.size(); i++) { word[i] = toLower(word[i]); } } int solution(string word, vector<string> pages) { int answer = 0; allLower(word); for (int i = 0; i < pages.size(); i++) { string& page = pages[i]; allLower(page); string myUrl = getMyUrl(page); urlToIndex[myUrl] = i; int base = calculateBase(page, word); int outer = calculateOuter(page, i); nodes.push_back({myUrl, base, outer, 0, 0}); } double maxValue = -1; for (int i = 0; i < pages.size(); i++) { Node presentNode = nodes[i]; string myUrl = presentNode.url; double linkScore = 0; for (int link : links[myUrl]) { Node nextNode = nodes[link]; linkScore += (double)(nextNode.base) / (nextNode.outer); } if (maxValue < linkScore + presentNode.base) { maxValue = linkScore + presentNode.base; answer = i; } } return answer; }
반응형'문제 풀이 > 프로그래머스' 카테고리의 다른 글
프로그래머스 - 등대 [C++] (0) 2024.03.08 프로그래머스 - 카드 짝 맞추기 [C++] (0) 2024.03.03 프로그래머스 - [1차] 추석 트래픽 [C++] (0) 2024.03.02 프로그래머스 - 2차원 동전 뒤집기 [C++] (0) 2024.03.01 프로그래머스 - 카운트 다운 [C++] (0) 2024.03.01