▶문제설명
코딩테스트 연습 > 완전탐색 > 소수 찾기
▶ 설계
number의 길이를 n이라고 하자.
n개의 숫자들 중에 1 ~ k 개를 뽑아서 순열을 생성한 뒤 정수로 변환하고 해당 정수가 중복되지 않도록하여 소수인지 아닌지 판별해서 개수를 반환하는 함수를 구현해야 한다.
조합의 경우에는 순서를 고려하지 않고 k개를 뽑아내므로 조합만으로는 풀 수 없다.
(간단히 예를 들면 1, 3, 2 를 뽑아낼 뿐이지 132, 123, 213, 231, 312, 321와 같이 순열을 뽑아내는 방법이 아니기 때문이다.)
n개의 숫자들 중 k개를 뽑아서 순열을 만들기 위해서 재귀함수를 구현하면 될 것으로 보인다.
1 2 3 4 5 6 7 8 9 10 11 | void permutation(string& numbers, int idxNow, int k, int cntSelectedNum, vector<int>& ansPrimeNumbers){ if(cntSelectedNum == k){ return; } for(int i=idxNow ; i<numbers.length() ;i++){ swap(numbers[i], numbers[idxNow]); permutation(numbers, idxNow+1, k, cntSelectedNum+1, ansPrimeNumbers); swap(numbers[i], numbers[idxNow]); } } | cs |
종료 조건은 cntSelctedNum(선택된 숫자들의 개수)이 k와 같을 때이다.
이 때가 바로 k개의 숫자로 순열이 만들어진 시점이므로 문자열을 정수로 바꿔 소수인지 판별하면 된다.
하지만 순열이 중복될 수 있으므로
1 | set<int> checkSet; | cs |
set 자료구조를 사용해서 중복을 제거해주도록 하자.
▶ 구현
직접 정의한 순열을 생성하는 permutation()은 세 번째 인자로 1부터 numbers.length()까지의 값을 주어 호출했다.
그러면 1개를 뽑아 만든 순열, 2개를 뽑아 만든 순열, ... , numbers.length()개를 뽑아 만든 순열을 생성한다는 의미다.
cntSelectedNum == k가 참이 되어 순열이 생성된 시점에
문자열을 정수로 바꾸고 checkSet에 이미 해당 정수가 있는지 확인해서 중복을 체크했다.
set 자료구조는 key값이 중복되지 않도록 구현되어 있기에 가능했다.
1 2 3 4 5 6 7 | int getInt(string strNum){ int ret = 0; for(int i=0; strNum[i] ; i++){ ret = (ret*10) + strNum[i]-'0'; } return ret; } | cs |
위와 같은 소스를 통해 문자열을 정수로 변환할 수 있었다.
제일 앞쪽에 있는 숫자부터 순차적으로 현재 정수에 10을 곱한 값에다 더해주었다.
이 방법으로 "0234"가 정수 234로 바뀌는 과정을 보면
0(초기값) -> 0 -> 2 -> 23 -> 234
이런식으로 값이 만들어진다는 것을 알 수 있다.
또한, 만들어진 정수가 소수인지 판별해서 카운트 해줘야 한다.
소수를 판별하는 부분은 [2, sqrt(num)] 범위를 훑으면서 자기 자신을 제외한 수로 나누어 떨어지는지 확인해서 그런 경우가 하나라도 있다면 false를 반환하도록 구현했다.
▶Solution
'■ 알고리즘 문제 풀이 > 프로그래머스' 카테고리의 다른 글
[프로그래머스] 카펫 (0) | 2019.12.17 |
---|---|
[프로그래머스] 단어 변환 (0) | 2019.12.16 |
[프로그래머스] 다리를 지나는 트럭 (0) | 2019.12.13 |
[프로그래머스] 여행경로 (0) | 2019.12.12 |
[프로그래머스] 기능개발 (0) | 2019.12.12 |