완전 검색, 고지식 (Brute force)
[알고리즘] 완전 검색, 무차별 대입 검색(Brute Force Search) 순차 검색 Searching 이거 해 보고 다른 알고리즘으로 성능 개선 모든 경우의 수 생성 후 다 더해 봄
- ex) 부분 집합 갯수 구하려면 원소 갯수만큼 for문 돌리기, in / not 사용 → 비효율
- 적용 예시: 부분 집합의 합
유한한 정수 집합의 부분 집합의 합이 0되는 경우 있는지 찾기 ex) (-7, -3, -2, 5, 8) → (-3, -2, 5) 전체 부분 집합의 갯수: 2^(원소의 갯수) → 원소 있다 / 없다의 0 / 1 비트 문제로 치환 가능 이 경우 비트는 index의 역할
-
비트연산자 활용 Bitwise
full_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] n = 10 #원소 갯수 n = len(arr) for i in range (1<<n): #전체 부분집합 갯수만큼 돎 for j in range (n): if i & (1<<j): #->이게 핵심! temp_list.append (subset[j]) # , end= ","는 print에만 쓸 수 있는 함수 ``` -
시프트 연산자 (<<, >>, >>>): 비트들을 다른 자릿수로 이동시키는 방식으로 동작한다.
-
비트 = 2진수이므로 자릿수 옮기는 건 2씩 곱하기 / 나누기
-
If i & (1<<j):
전체 부분 집합 갯수 → 집합 원소 (들어감 / 안 들어감) 모든 경우 실험해서 출력
case 1) i == 3, n = 5, full_list = [1, 2, 3, 4, 5] i는 이진수로 11, 이 경우에 모든 j는 0 ~ 4 순회하면서 2^j를 만듦 (<<연산자로 2배씩 계속 곱함) j == 0: 11 - 1 j == 1: 11 - 10 j == 2: 11 - 100 j == 3: 11 - 1000 j == 4: 11 - 10000 -> &연산자는 모두 1이어야 1, 나머지는 0. -> if는 0만 아니면 True j == 0: 11 01 -- 01 -> 1, True j == 1: 11 10 -- 10 -> 2, True j == 2 ~ 4: 11 00 -- 00 -> 0, False -> 최종 출력: full_list[0], full_list[1] # 1, 2