알고리즘 부셔버렷/ProblemSolving
[프로그래머스] 소수 찾기 (문제 설명, 해결 과정, 코드 전문, c++)
Unagi_zoso
2022. 6. 10. 19:25
문제 설명 |
본 문제는 프로그래머스의 소수 찾기 문제입니다.
numbers | return | example.. |
"17" | 3 | 7, 17, 71 |
"011" | 2 | 11, 101 |
해결 과정 |
주어진 문자열의 숫자들로 구할 수 있는 모든 부분집합들 구합니다.
ex) "17" => 1, 17, 71
부분집합을 구하는 과정에서 부분집합의 앞자리가 0이거나 부분집합이 0이나 1인(1은 소수에 포함x) 경우를 제외하고
구할 수 있었던 모든 부분집합을 배열에 저장합니다. 이때 제가 구현한 방법에서는 문자열 내에 중복되는 숫자가 있을 시
중복된 부분집합을 가질 수있어서, 부분집합을저장한 배열의 중복된 부분을 제거합니다.(erase unique 기법을 사용하였습니다.) 이후 소수인지를 판별 함수를 통해 부분집합배열을 판단하고 판단되어진 횟수를 반환합니다.
코드 전문 |
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
vector<int> vec;
bool isPrime(int num)
{
for (int i = 2; i <= sqrt(num); i++)
if (num%i == 0)
return false;
return true;
}
void comb(string s, int pos, string cur_s)
{
if (pos == s.size())
{
if (cur_s[0] == 0 || stoi(cur_s) == 0 || stoi(cur_s) == 1) return;
vec.emplace_back(stoi(cur_s));
return;
}
comb(s, pos+1, cur_s+s[pos]);
comb(s, pos+1, cur_s);
}
int solution(string numbers) {
int answer = 0;
if (numbers == "0") return 0;
// take vector all subset
sort(numbers.begin(), numbers.end());
do
{
comb(numbers, 0, "");
}
while (next_permutation(numbers.begin(), numbers.end()));
// remove overlap
sort(vec.begin(), vec.end());
vec.erase(unique(vec.begin(), vec.end()), vec.end());
for (auto num : vec)
if (isPrime(num) == true) answer++;
return answer;
}
느낀 점 (잡설 99% , 배운점 1%(많은 편)) |
더보기
부분집합을 만들어보았고 중복된 부분을 제거하기 위해 erase unique 기법을 사용하였습니다.
어제 erase remove idiom에 관한 글을 적었는데 그와 비슷한 맥락인 이 기법을 사용할 수 있어 재밌었습니다.
소수 부분도 재밌었습니다. 에라스토네스의 체라는 것도 알게 되었습니다.
긴 글 읽어주셔서 감사합니다.
부족한 점이 있다면 부디 알려주시면 감사하겠습니다.