Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

경쟁 프로그래밍 초보자를 위한 필수 C++ 트릭 15선

경쟁 프로그래밍에서는 문제를 빠르고 정확하게 해결하는 능력이 무엇보다 중요합니다. 이 글에서는 코딩 시간을 단축하고 코드 효율을 높여 주는 실용적인 C++ 트릭들을 소개합니다. 비트 연산부터 STL 알고리즘까지, 초보자도 바로 활용할 수 있는 팁들을 하나씩 살펴보겠습니다.

1. % 연산자 없이 홀수·짝수 판별하기

비트 AND 연산을 활용하면 나머지 연산자(%) 없이도 숫자의 홀짝을 쉽게 판별할 수 있습니다. 모든 홀수는 최하위 비트(LSb)가 1이므로, 숫자와 1을 AND 연산했을 때 결과가 0이 아니면 홀수입니다.

if ((n & 1) != 0){
// 홀수
} else {
// 짝수
}

2. 시프트 연산자로 빠른 곱셈과 나눗셈

2의 거듭제곱으로 곱하거나 나눌 때는 시프트 연산자가 일반 곱셈·나눗셈보다 훨씬 빠릅니다. 왼쪽 시프트(<<)를 n번 수행하면 2ⁿ을 곱한 것과 같고, 오른쪽 시프트(>>)를 n번 수행하면 2ⁿ으로 나눈 것과 같습니다.

x = 40;
y = x << 2; // x에 4를 곱한 것과 동일, y = 160
cout << y;

x = 40;
y = x >> 2; // x를 4로 나눈 것과 동일, y = 10
cout << y;

3. 세 번째 변수 없이 두 숫자 교환하기

+와 - 연산자로도 가능하지만, XOR 연산을 이용하면 임시 변수 없이 두 변수의 값을 더 깔끔하게 교환할 수 있습니다.

// x와 y 교환
x ^= y;
y ^= x;
x ^= y;

4. strlen() 함수 없이 문자열 순회하기

strlen() 함수를 사용할 수 없는 상황이라면, 문자열의 끝이 널 문자('\0', 즉 0)라는 점을 이용해 반복문을 작성하면 됩니다. 해당 위치의 문자가 유효한(0이 아닌) 동안만 순회하면 됩니다.

for(int i = 0; s[i]; i++){
cout << s[i];
}

5. push_back() 대신 emplace_back() 사용하기

vector 같은 STL 컨테이너에 요소를 추가할 때 흔히 push_back()을 사용하지만, emplace_back()을 쓰면 훨씬 빠릅니다. 이 함수는 다른 곳에 메모리를 새로 할당하지 않고 컨테이너 내부에 직접 객체를 생성하기 때문입니다.

6. 내장 GCD 함수 활용하기

C++에는 최대공약수(GCD)를 구하는 내장 함수가 있어 다양한 상황에서 활용할 수 있습니다.

__gcd(x, y) // x와 y의 최대공약수 계산

7. 배열 크기 제한 이해하기

main 함수 안에서 선언하는 지역 배열은 스택 메모리 한계 때문에 약 10⁶ 정도가 최대 크기입니다. 반면 전역으로 선언하면 약 10⁷까지 선언할 수 있습니다.

8. 로그 연산으로 최상위 자릿수 구하기

log10 연산을 응용하면 어떤 숫자든 최상위 자릿수를 손쉽게 구할 수 있습니다.

n = 4578;
double k = log10(n);
k = k - floor(k);
int x = pow(10, k); // x는 최상위 자릿수

9. 로그 연산으로 자릿수 개수 구하기

반복문 없이 log10을 이용해 자릿수를 바로 계산할 수 있습니다.

n = 4578;
int digit_count = floor(log10(n)) + 1;

10. 2의 거듭제곱인지 확인하기

비트 연산을 활용하면 숫자가 2의 거듭제곱인지 간단히 검사할 수 있습니다.

x = 1024;
bool check = x && (!(x & (x-1))); // true이면 2의 거듭제곱

11. all_of, any_of, none_of 알고리즘

C++의 내장 알고리즘을 사용하면 컨테이너의 원소들이 특정 조건을 만족하는지 한 번에 검사할 수 있습니다.

all_of(left, left + n, isPositive()); // 모두 양수인지 확인
any_of(left, left + n, isPositive()); // 하나라도 양수인지 확인
none_of(left, left + n, isPositive()); // 양수가 하나도 없는지 확인

12. copy_n으로 컨테이너 간 복사하기

copy_n 함수를 사용하면 한 컨테이너의 요소를 다른 컨테이너로 간편하게 복사할 수 있습니다.

int src[5] = {10, 20, 30, 40, 50};
int dest[5];
copy_n(src, 5, dest);

13. itoa로 연속된 값 생성하기

itoa 알고리즘은 시작 값부터 차례로 증가하는 연속된 값들의 범위를 생성할 때 유용합니다.

int arr[5] = {0};
char str[5] = {0};
itoa(arr, arr+5, 15); // {15, 16, 17, 18, 19} 생성
itoa(str, str+5, 'A'); // {'A', 'B', 'C', 'D', 'E'} 생성

14. 2진수 리터럴로 값 할당하기

숫자 앞에 0b 접두사를 붙이면 해당 값이 2진수임을 명시할 수 있습니다.

int x = 0b1101; // x는 13

15. 조건 연산자 대신 키워드 사용하기

C++에서는 &&, || 같은 기호 대신 'and', 'or' 같은 키워드를 그대로 사용할 수도 있습니다.

x = 10;
if(x < 10 and x > 5)
cout << "True" << endl;
else
cout << "False" << endl;
// True 출력