Python

[Python] 9. 비트 연산자를 이용한 부분집합 구하기

개발자 뭄뭄 2022. 8. 13. 22:48
반응형

오늘은 비트 연산자를 이용한 부분집합 구하기에 대해서 정리해보도록 하겠다.

우선 완성된 코드는 이렇다.

array = [1, 2, 3]
n = len(array)

for i in range (1<<n):
	for j in range(n):
		if i & (1<<j):
			print(array[j], end=" ")
	print()
1 
2 
1 2 
3 
1 3 
2 3 
1 2 3

참고로 출력값은 오른 쪽과 같다.

자, 그러면 이제 하나하나씩 뜯어보자.

먼저 부분집합의 개수는 각 원소마다 들어가거나/들어가지 않거나 2가지 경우가 있다.

따라서 원소의 개수가 n 일 때, 2n2^n 만큼의 부분집합이 생긴다. (공집합 포함)

위 예에서는 array의 원소 개수가 3이므로, 총 8개의 부분집합이 생긴다.

1. for i in range (1<<n)

‘<<’ 은 비트 쉬프트 연산자(shift) 이다. 쉽게 말해 1을 왼쪽으로 한칸씩 옮긴다고 생각하면 된다.

여기에서 range(1<<n)2n2^n 가지 경우의 수에 대해서, 반복하기 위해서 사용한 범위이고.

i는 0부터 (2n2^n-1)까지의 수를 2진수로 바꾼 값을 말한다. 즉

i = (0 0 0), (0 0 1), (0 1 0), (0 1 1) ….. (1 1 1) 로 반복문이 돌아간다.

2. for j in range (n)

j는 리스트의 인덱스로써 사용되고,

이 경우에 j는 j = 0, 1, 2 에 대해서 돌아간다.

3. if i & (1<<j) :

이 줄이 핵심이다. 여기서부터는 그림과 말을 통해서 설명해보도록 하겠다.

여기에서 (1<<j)는 j번만큼 1을 왼쪽으로 옮긴 것이라고 이해하면 된다.

예를 들어 j = 0 이면, 1<< j는 001 이고,

j = 1이면, 1<<j = 010 이다.

비트연산자에서 &는 둘 다 1일때만 1이고, 하나라도 0이면 0이다.

그럼 언제 if i & (1<<j) 가 실행이 될까?

파이썬에서는 ‘0’이 False이고, 그 외의 수는 True이기 때문에,

if 문이 True가 될 때, 즉 i&(1<<j)의 값이 1일 때 아래 print문을 실행하게 된다.

예를 들어 5번째 반복문 즉, i = 101인 상황을 가정해보자.

다음 반복문에서 j = 0, j = 1, j = 2 으로 세번 반복문이 돌아가며

이 때 i<<j 값은 각각 001, 010, 100 이다.

i&1<<j 의 값이 1이 되는 경우는 j = 0일때와 j =2 일때다,

이 때 print의 마지막에 ,end = “ “ 가 있기때문에

a[0] 값인 1과 a[2] 값인 3이

1

3

이 아닌 1 3 의 형태로 한줄로 출력된다.

다시 맨 위로 올라가서 코드 실행 결과의 5번째 줄을 보자! 1 3 인 것을 알 수 있다.

이런식으로 8번을 반복해서 부분집합을 출력하는 것이다.

나머지 경우에 대해서는 직접 생각하고, 돌려보자.


Uploaded by N2T

반응형