소수 판별
소수란 1보다 큰 자연수 중에서 1과 자기 자신을 제외한 자연수로 나누어떨어지지 않는 자연수이다.
python으로 구현한 소수 판별(기본)
def isPrimeNum(x) :
for i in range(2, x) :
# 2 ~ (x-1) 중 나누어 떨어지는 수가 있으면 소수가 아님
if(x % i == 0) :
return False
return True
print(isPrimeNum(4))
print(isPrimeNum(7))
➡️ 2부터 (x-1)까지 모든 자연수에 대하여 연산을 수행해야 하기 때문에
시간 복잡도는 이다.
약수의 성질
모든 약수가 가운데 약수를 기준으로 곱셈 연산에 대해 대칭을 이룬다.
예를 들어, 16의 약수는
1 2 4 8 16 --> (1, 16), (2, 8)은 대칭이다.
따라서 특정한 자연수의 모든 약수를 찾을 때 가운데 약수(제곱근)까지만 확인하면 된다.
python으로 구현한 소수 판별(개선) - 약수의 성질
import math
def isPrimeNum(x) :
# math 라이브러리를 굳이 사용하지 않아도 된다.
# for i in range(2, int(math.sqrt(x)) + 1) :
# x의 제곱근까지만 실행
for i in range(2, int(x**(1/2)) + 1) :
if(x % i == 0) :
return False
return True
print(isPrimeNum(4))
print(isPrimeNum(7))
특정 범위 안에 존재하는 모든 소수 찾기
에라토스테네스 알고리즘
다수의 자연수에 대하여 소수 여부를 판별할 때 사용하는 대표적인 알고리즘.
에라토스테네스 알고리즘 구현 :
#include <iostream>
#include <cmath>
using namespace std;
void Eratosthenes(int n, bool* arr) {
for (int i = 2; i <= sqrt(n); i++)
{
// 남은 수를 제외한 남은수의 배수들 지우기(false 만들기)
if(arr[i]) {
int j = 2;
while(i * j <= n) {
arr[i * j] = false;
j += 1;
}
}
}
for (int i = 2; i <= n; i++)
{
if(arr[i]){
cout << i << " ";
}
}
}
int main(void){
// 2 ~ 1,000까지 소수의 개수 구하기
int n = 1000;
// 2 ~ 1,0000 True로 초기화 (True : 소수, False : 소수 아님)
bool* arr = new bool[n+1];
memset(arr, true, n+1 * sizeof(bool));
Eratosthenes(n, arr);
return 0;
}
투 포인터(Two Pointers), 특정한 합을 가지는 부분 수열 찾기
투 포인터 알고리즘은 리스트에 순차적으로 접근해야 할 때 두 개의 위치를 기록하면서 처리하는 알고리즘
특정한 합을 가지는 부분 연속 수열 찾기
아이디어
문제 풀이
n = 5
m = 5 # 특정한 합
arr = [1, 2, 3, 2, 5]
cnt = 0
local_sum = 0
start, end = 0, 0
for start in range(n) :
local_sum = arr[start]
while True :
local_sum += arr[end]
if start == end :
local_sum -= arr[start]
if end >= n :
break
elif m == local_sum :
cnt += 1
break
elif local_sum < m :
end += 1
elif local_sum > m :
break
print(cnt)
투 포인터(Two Pointers), 구간합 계산하기
구간 합(Inerval Sum) 문제 설명
아이디어
접두사 합(Prefix Sum) : 배열의 맨 앞부터 특정 위치까지 합을 미리 구해 놓는 것
구간합 문제 풀이 :
n = 5
data = [10, 20, 30, 40, 50]
prefix_sum = 0
prefix = [0]
for i in data :
prefix_sum += i
prefix.append(prefix_sum)
left, right = 1, 3
print(prefix[right] - prefix[left - 1])
순열 (Permutation)
순열이란 서로 다른 n개에서 r개를 선택하여 일렬로 나열하는 것.
1, 2, 3에서 2개를 선택하여 나열
➡️ (1,2), (1,3), (2,1), (2,3), (3,1), (3,2)
python의 iterools library을 사용하여 순열(Permutations)을 간단하게 구현할 수 있다.
단, permutations() 함수를 통해 결과는 list가 아니다. 따라서 list로 casting하여 결과를 받는 것이 일반적이다.
python의 iterools library의 permutations() 함수
import itertools
data = [1, 2, 3]
for x in itertools.permutations(data, 2) :
print(list(x))
조합 (Combination)
조합이란 서로 다른 n개에서 순서에 상관없이 서로 다른 r개를 선택하여 나열하는 것.
1, 2, 3에서 2개를 선택하여 나열
➡️ (1,2), (1,3), (2,3)
python의 iterools library을 사용하여 순열(Combination)을 간단하게 구현할 수 있다.
단, combinations() 함수를 통해 결과는 list가 아니다. 따라서 list로 casting하여 결과를 받는 것이 일반적이다.
python의 iterools library의 combination() 함수
import itertools
data = [1, 2, 3]
for x in itertools.combinations(data, 2) :
print(list(x))