깊이 우선 탐색 문제
코딩테스트 연습 - 불량 사용자 | 프로그래머스
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
vector<int> bit;
bool ft_can_match(string user, string ban) {
if (user.length() != ban.length())
return (false);
for (int i = 0; i < user.length(); i++) {
if (ban[i] == '*') {
continue;
}
else if (user[i] != ban[i]) {
return (false);
}
}
return (true);
}
//https://dpdpwl.tistory.com/39
int dfs(vector<string> user_id, vector<string> banned_id, int bit_flag, int deep) {
if (deep == banned_id.size()) {
bit.push_back(bit_flag);
return (0);
}
for (int i = 0; i < user_id.size(); i++) {
if (!(bit_flag & (1 << i)) && ft_can_match(user_id[i], banned_id[deep]) == true) {
int temp = dfs(user_id, banned_id, bit_flag + (1 << i), deep + 1);
}
}
return (0);
}
// 제한사항이 많을 수 밖에 없음. 애초에 말이 안되는, 문제를 위한 문제기 때문
// 특히 응모한 사용자 아이디가 중복되지 않는다거나
// 불량사용자의 아이디는, 응모자 아이디 중 하나에 해당한다와 같은
// 갖가지의 전제가 붙을 수 밖에 없음
// banned_id size 만큼 재귀를 일으키면서, 다 돌게되면 카운팅.
int solution(vector<string> user_id, vector<string> banned_id) {
int answer = 0;
dfs(user_id, banned_id, 0, 0);
std::vector<int>::iterator it;
sort(bit.begin(), bit.end());
it = unique(bit.begin(), bit.end());
bit.erase(it, bit.end());
answer = bit.size();
bit.erase(bit.begin(), bit.end());
return answer;
}
int main() {
int answer;
//string vector initialization
//https://www.delftstack.com/ko/howto/cpp/how-to-initialize-a-vector-in-cpp/
vector<string> user_id = {"frodo", "fradi", "crodo", "abc123", "frodoc"};
vector<string> banned_id1 = {"fr*d*", "abc1**"};
answer = solution(user_id, banned_id1);
cout << "ex1: " << answer << endl;
vector<string> banned_id2 = {"*rodo", "*rodo", "******"};
answer = solution(user_id, banned_id2);
cout << "ex2: " << answer << endl;
vector<string> banned_id3 = {"fr*d*", "*rodo", "******", "******"};
answer = solution(user_id, banned_id3);
cout << "ex3: " << answer << endl;
}
******
와 같은 banned id가 넘어온다면, 분기가 굉장히 복잡해짐bit_flag
를 하나 주고, bit 연산으로 데이터를 저장하는 식으로 풀이순열의 반복제거
를 하는 문제로 둔갑...