✨비트 연산자 가지고 놀기

phoenixKim·2022년 7월 23일
0

백준 알고리즘

목록 보기
67/174

비트 연산자

😅비트의 not 연산자 : ~

  • 논리 연산자의 !와는 다르다!

    논리 연산자의 !은 거짓인지를 확인하는 것이고, 비트에 영향을 주지 않음!

// 그냥 외우자.

1. 인덱스로 이동시키기

: (1 << idx)

2. 인덱스를 on하기

: num |= (1 << idx)

3. 인덱스가 on이면 off, off면 on시키기

: num ^= (1 << idx)

4. 모든 원소를 on 시키기

: (1 << n) - 1

5. 인덱스를 off하기

: num & ~(1 << idx)

6. 비트가 on이 되어 있는지 확인하기

if(s &(1 << idx)) // == 1로 하면 안됨!

비트연산자를 어디에 사용할까?

수많은 데이터가 있는 벡터를 map에 사용하지 않고, 하나의 데이터에다가
넣어 놓은 상태일 때

  • 1) ++ 연산을 하게 되면 , 모든 원소에 대한 경우의 수를 탐색 할 수 있음.

n의 크기를 가지고 있는 비트의 모든 경우의 수
-> 만약에 4라고 한다면? 0000 ~ 1111 까지임.
이것은 이렇게 표현할 수 있음.
(1 << 4) - 1 => 15출력

사과 , 배 , 포도 , 복숭아를 선택할 수 있는 모든 경우의 수

1) 모든 경우의 수를 만듦. -> (1 << 4) : i
2 - 1) 원소 하나하나를 순회해야 함. -> v.size() : j
2 - 2) 원소 하나 하나를 체크함. -> i & (1 << j)

  • 주의할 점. 조건 체크할때
    if ((i & (1 << j) ) == 1) 로 하면 안됨.
    -> 원소가 1이라는 것은 2의 n승이므로, 1로 하면 안됨!

  • 코드

#include <iostream>
using namespace std;
#include <vector>
#include <string>

int main()
{
	vector<string> fruits = { "사과" ,"딸기", "포도", "배" };

	// 4개의 원소를 나타낼수 있는 모든 경우의 수.
	for (int i = 0; i <= (1 << 4) - 1; ++i)
	{
		// 모든 인덱스를 하나씩 확인하는 구간.
		for (int j = 0; j < fruits.size(); ++j)
		{
			//i & 1? //모든 원소와 경우의 수를 확인해야 할듯함.

			// 하나의 원소를 모든 경우의 수와 확인하는 방법
			//1 << j;
			//int n = i & (1 << j);
			//cout << n << endl;
			if ((i & (1 << j)))
				//if ((i & (1 << j) ) == 1) 로 하면 안됨. 
				// 자릿수는 2의 승수이므로 1 2 4 8 순으로 나옴.
			{
				cout << fruits[j] << " ";
			}
			else
				cout << " -- ";
		}
		cout << endl;
	}

}


  • 코드
#include <iostream>
#include <vector>
using namespace std;
#include <bitset>


int main()
{
	// 비트 가지고 놀기
	int b = 0b1111; 
	cout << b << endl;
	cout << bitset<8>(b) << endl;

	// 내가 지정한 인덱스를 on, off 하기 
	// on 할 때는 |= (1 << idx)
	// off 할 때는 |= (0 << idx)
	int a = 0b0000;
	cout << "초기값은 ? : ";
	cout << bitset<8>(a) << endl;

	// on은 어떻게 만들까? 
	// 1을 << 시프트 할때마다 1 , 10 , 100 , 1000
	// 0이 뒤에 따라 온다는 것을 알고 있어야 함.
	// 시프트 한 후, + 더하기를 하면됨!
	int idx = 2;
	a |= (1 <<idx);
	cout << idx << "번째 인덱스의 값을 on하기 " << endl;
	cout << bitset<8>(a) << endl;

	idx = 3;
	a |= (1 << idx);
	cout << idx << "번째 인덱스의 값을 on하기 " << endl;
	cout << bitset<8>(a) << endl;

	// 해당 인덱스에 off는 어떻게 만들까?
	// 시프트 할때마다 뒤에 0씩 생긴다는 것을 염두해야 함.
	// 기존의 값의 인덱스에 off를 해야 하는데,,, 
	// 앞을 0인 값으로 만들어야 함.
	// 그럼 반전을 하게 되면 
	// 예를 들어 100000
	// 011111 이 됨.
	// 연산을 할 값과 어떤 연산을 해야 할까?
	// or를 하게 되면, 그냥 + 이므로 안됨.
	// 기존의 값의 나머지 인덱스는 그대로 적용하기 위해서 
	// and를 사용하자. 
	
	idx = 3;
	a &=  ~(1 << idx);
	cout << idx << "번째 인덱스의 값을 off하기 " << endl;
	cout << bitset<8>(a) << endl;

	// n개의 집합에서 모든 비트를 1로 만들기 
	// 어떻게 해야할까?
	// 3개의 집합일 경우 : 0 0 0 으로 나타낼 수 있음. 
	// 1 1 1 로 만들고 싶다는 거자나
	// 그러면 4개의 집합 1 0 0 0 으로 먼저 만들어 놓은 후에
	// - 1 감산을 하자.
	
	cout << "모든 비트를 1로 만들기" << endl;
	int n = (1 << 4) - 1;
	cout << bitset<4>(n) << endl;

}
  • 결과
profile
🔥🔥🔥

0개의 댓글

관련 채용 정보