C++ 유용한 문법들

이 글은 유용한 문법 및 함수들을 소개하는 글입니다.
"요약 노트" 정도로 생각해주시면 될 것 같습니다.
그래서 구체적인 원리나 주의사항, 확장 가능성에 대한 이야기는 생략하겠습니다. 궁금한 부분에 대해 댓글로 남겨주시면 답해드리도록 하겠습니다 :)
제 원문은 이 링크입니다.
이를 축약해서 백준 블로그에 올립니다.

  • f, l은 앞 주소와 뒷 주소를 나타내고, 여러 개면 번호를 1부터 차례대로 붙였습니다. (f, l은 first와 last의 약자, [f,l)임에 유의하세요)
  • func은 호출할 함수를 나타냅니다.
  • 비교기반 함수에 대해서는 cmp 함수를 추가하는 것이 항상 가능하므로, 생략하였습니다. (cmp는 compare의 약자)
  • max가 있으면 min도 있습니다.
  • 맨 첫 줄에 #include <bits/stdc++.h> 구문을 작성했다고 전제합니다.

노트처럼 사용하실 수 있도록 모아놓고 싶었습니다. 의견은 언제든 환영이고, 앞으로도 이 글은 지속적으로 개선해나가겠습니다.

입출력

  • cin.tie(0)->sync_with_stdio(0): 속도 개선
  • endl'\n'로 대체하기: 속도 개선
  • getline(cin, s): 공백까지 통째로 한 줄 입력

서식

  • 소수점 자릿수 조정 (ex. 소수점 아래 6자리)
    1. printf("%.6f", a)
    2. cout << fixed로 소수점 고정 후 cout.precision(6)로 정밀도 조정

일반

비트 연산

  • 공식 (z: 정수, n: 자연수)
    • ~z는 -z-1와 같다
    • z&(1<<k) ⇔ n의 2진법 상 k+1번째 자릿수
    • !n&(n-1) ⇔ n은 2의 거듭제곱수
    • long long이라면, n&(1LL<<k)
    • 홀수면 n&1=1, 짝수면 n&1=0, ~n&1=1
  • __builtin_popcount(n), __builtin_popcountll(n): 비트 1의 개수

이진탐색 기반 함수

  • lower_bound(f, l, x): x보다 크거나 같은 최소 원소 위치 (O(log n), iterator를 반환)
  • upper_bound(f, l, x): x보다 큰 최소 원소 위치 (O(log n), iterator를 반환)

컨테이너의 조작

  • sort(f, l): 정렬 (O(n log n))
  • 역순정렬
    • sort(f, l, greater<int>())
    • sort(v.rbegin(), v.rend()) (STL만. 배열은 이거 ㄴㄴ)
  • reverse(f, l): 뒤집기 (O(n))
  • max_element(f, l): 최대 원소 (O(n))
  • fill(f, l, x): 채우기 (O(n), 임의의 자료형에 대해 가능)
  • 지우기
    • v.erase(i) (O(n))
    • v.erase(f, l) (O(n))
    • remove(f, l, x, y): 모든 x를 y로 바꾸기 (O(n))
    • remove_if(f, l, func, y): func(x)를 참으로 만드는 모든 x를 y로 바꾸기 (O(n))
  • v.erase(unique(f,l),l): 묶어버리기(즉, 연속한 같은 원소들을 하나로 만들기) (O(n))
  • swap(a, b): 두 변수의 값을 교체

수학

  • abs(x): 절댓값
  • gcd(x): 최대공약수 (O(log n))
  • lcm(x): 최소공배수 (O(log n))
  • next_permutation(f, l): 사전순으로 다음에 오는 순열 (O(n))
  • max(a, b): 더 큰 원소
  • max({a,b,c}) : 제일 큰 원소
  • max_element(f,l): 구간 내 최대 원소 (O(n))

매크로

매크로는 ()가 제일 중요합니다.

  • 유용한 매크로들
    • #define ALL(x) (x).begin(), (x).end(): 1+ALL(x)와 같은 식으로 사용할 수도 있음
    • #define SZ(x) (int)size(x): 자료형 명시를 하지 않으면 에러가 나므로 형변환
    • #define REP(i,a,b) for (int i = (a); i <= (b); ++i) 전형적인 for문을 직접 쓰는 것은 너무 소모적이고, 인자를 헷갈릴 수 있음

디버깅

  • assert(조건문)
  • #define debug(x) cout << #x << " is " << x << '\n'

작명

  • 자료형에는 UpperCamel!
    • ex. Point, SegmentTree, DisjointSetUnion
  • 함수나 변수에는 lowerCamel! 혹은 snail_case!
    • ex. countEven, isPrime
    • ex. count_even, is_prime
    • 개취.
  • 매크로나 상수에는 언더바와 대문자!
    • ex. MOD, MAX_N

추가 사항

if문 안에서만 써먹고 버리고 싶은 변수가 있다면~~

  if (int x = f(); is_true(x)) {
        func(x);
  }

뭐 이런식으로 써먹을 수 있다고 합니다

Reference


댓글 (9개) 댓글 쓰기


wonkyum256 5달 전

std::upper_bound는 x보다 큰 첫번째 원소, std::lower_bound는 x보다 크거나 같은 첫번째 원소를 찾는 함수입니다.


dohoon 5달 전

오타 지적 감사합니다!!


ktasha45 3달 전

배워갑니다 감사합니다!!


tasddc 2달 전

감사합니다!


rafle 2달 전

주의사항은 직접 찾아보라고 하셨지만, 노트로 쓰기 위해서는 아무리 그래도 필요한 내용이 더 있지 않나 싶네요.

  1. 어떤 헤더에 들어가있는 함수인가
  2. 함수의 반환형이 어떤 형태인가. (lower_bound의 경우는 iterator)
  3. 글쓴이 입장에서 쓴 말들이 과연 당연한가 (f, l, cmp, 작명 등)

dohoon 2달 전

의견 정말 감사합니다! 우선, 이 노트는 최대한 심플하게 유용한 함수들을 소개하는 것이 취지임을 밝힙니다.

  1. 모든 함수가 <bits/stdc++.h> 헤더에 포함되어 있습니다. 이를 명시하지 않았는데, 바로 적도록 하겠습니다!
  2. 함수의 반환형은 제 원문에서는 밝혔으나 여기에 옮기지 않았는데, lower_bound와 upper_bound에 대해서는 반환형을 명시하도록 하겠습니다. 반환형을 명시해야 할 다른 함수가 있다면 알려주시면 감사하겠습니다 :)
  3. 처음에는 f를 first로, l을 last로 표기하였지만, 긴 변수명이 오히려 간결함을 해친다고 판단하였고, 이 변수들은 글 전체에 걸쳐 반복되기에 미리 명시하고 작성하는 편이 좋다고 판단했습니다. (cmp의 경우 잘 알려졌다고 생각합니다) 다만, 미리 명시하는 부분은 더 구체적일 필요가 있어보이므로 수정하겠습니다 :)

즐거운 백준 되세용 😆


clock 23일 전

그렇게 크게 유용한건 아닌데 2년전쯤 코드포스에서 어떤 분이 홀짝 판별을 신기하게 하신걸 본적이 있습니다

if(i&1) {
        //when i is odd
}
if(~i&1) {
        //when i is even
}

dohoon 23일 전

감사합니다! 바로 추가하겠습니다!


ktasha45 23일 전

오.. 감사합니다