48: 템플릿 메타프로그래밍, 하지 않겠는가? 템플릿 메타프로그래밍(template metaprogramming: TMP)은 컴파일 도중에 실행되는 템플릿 기반의 프로그램을 작성하는 일을 말한다. 템플릿 메타프로그램은 C++ 컴파일러가 실행시키는, C++로 만들어진 프로그램이다. TMP에는 엄청난 강점이 두 개나 있다. TMP를 쓰면 다른 방법으로는 까다롭거나 불가능한 일을 굉장히 쉽게 할 수 있다. 템플릿 메타프로그램은 C++ 컴파일이 진행되는 동안에 실행되기 때문에, 기존 작업을 런타임 영역에서 컴파일 타임 영역으로 전환할 수 있다. 몇몇 에러들을 컴파일 도중에 찾을 수 있다. 추가적으로, 모든 면에서 효율적일 여지가 많다. 실행 코드가 작아지고, 실행 시간도 짧아지며, 메모리도 적게 잡아먹는다. 항..
전체 글

문제 풀이 정렬, 누적 합 문제이다. 각각의 컬러공의 크기 이하의 컬러공을 모두 탐색한다면 O(N * N)으로 시간초과이다. 컬러공을 한 번만 순회하여 문제를 해결해야 한다. 컬러공을 크기의 오름차순으로 정렬한다. 정렬한 컬러공을 처음부터 탐색하면서 현재 i까지의 크기의 합을 구한다. 그 합에서 지금까지 나온 공들 중에서 i번 공과 같은 색을 가진 공들을 뺀다. 그 합에서 지금까지 나온 공들 중에서 i번 공과 같은 무게를 가진 공들을 뺀다(크기 순으로 정렬되어 있으므로 i번 공보다 크기가 큰 공은 현재까지 합해지지 않았다). 이렇게 하면, i번 공과 색상과 크기가 모두 같은 공은 총 두 번 빠진다. 그러므로, 지금까지 나온 공들 중에서 i번 공과 같은 색과 같은 크기를 가진 공들은 한 번 더해줘야 올바른..
47: 타입에 대한 정보가 필요하다면 특성정보 클래스를 사용하자 STL의 유틸리티라고 불리는 템플릿의 advance라는 템플릿을 보자. 이 템플릿은 지정된 반복자를 지정된 거리만큼 이동시키는 것이다. template void advance(IterT& iter, DistT d); STL 반복자는 지원하는 연산에 따라 다섯 개의 범주로 나뉜다. 입력 반복자(input iterator) 전진만 가능하고, 한 번에 한 칸씩만 이동하며, 자신이 가리키는 위치에서 읽기만 가능하다. 읽을 수 있는 횟수는 한 번뿐이다. 출력 반복자(output iterator) 입력 반복자와 비슷하지만 출력용인 점만 다르다. 쓰기만 가능하다. 순방향 반복자(forward iterator) 입력 반복자와 출력 반복자가 하는 일은 다 ..

문제 풀이 그래프 탐색, 누적합 문제이다. 횡단보도의 칸 중에서 물이 빠질 칸을 BFS로 탐색한다. BFS의 시작은 하수구 칸에서 시작한다. 현재 탐색 중인 칸의 상하좌우 칸 중에서, 현재 칸의 높이 이상인 칸은 물이 빠진다. 신발을 딛을 수 있는 방법의 수는 2차원 배열의 누적합으로 구한다. 위의 그림에서 초록색 영역의 합을 구해보자. 파란색 영역을 모두 한번씩 더한다면 빨간색 영역은 두 번 더해진다. 그러므로, 파란색 영역을 한번 더하고, 빨간색 영역을 한번 빼면 초록색 영역의 합을 구할 수 있다. for (int i = 1; i N >> M; cin >> h >> w; for (int i = 1; i road[i][j]; } } memset(water, true, sizeof(water)); int..
46: 타입 변환이 바람직할 경우에는 비멤버 함수를 클래스 템플릿 안에 정의해 두자 항목 24에서 모든 매개변수에 대해 암시적 타입 변환이 되도록 만들기 위해서는 비멤버 함수밖에 방법이 없다고 했었다. 이번엔 템플릿의 영역에서 알아보자. template class Rational { public: Rational(const T& numerator = 0, const T& denominator = 1); const T numerator() const; const T denominator() const; }; template const Rational operator*(const Rational& lhs, const Rational& rhs) {...} Rational onHalf(1, 2); Rationa..

문제 풀이 구현, 시뮬레이션 문제이다. 원판을 2차원 배열로 생각하고 처리한다. 원판을 회전시킬 때, 끝과 처음이 연결되어 있는걸 주의해야 한다. 원판과 인접한 수를 탐색할 때, BFS로 인접한 수가 현재 수와 같은 원판의 위치를 탐색한다. 탐색의 결과로 수를 지울지, 평균을 구할지를 결정한다. 코드 #include #include #include #include using namespace std; typedef struct { int x; int y; }type; queue bfs; int circles[51][51]; bool visited[51][51]; int move_x[4] = { 0, 0, 1, -1 }; int move_y[4] = { 1, -1, 0, 0 }; int main() { i..

2. 상자 예제를, 정점 버퍼 두 개를 사용해서 파이프라인에 정점들을 공급하도록 수정하라. 결론적으로 정점과 다른 입력 슬롯으로 색상 버퍼를 파이프라인에 묶어야 한다. 그러기 위해서는 색상을 위한 버퍼와 해당 버퍼의 뷰를 만들어서 IASetVertexBuffers 함수를 호출해야 한다. BoxApp 클래스에 색상 버퍼를 위한 멤버 변수를 만들어 준다. class BoxApp : public D3DApp { ... private: Microsoft::WRL::ComPtr ColorBufferCPU = nullptr; Microsoft::WRL::ComPtr ColorBufferGPU = nullptr; Microsoft::WRL::ComPtr ColorBufferUploader = nullptr; ... ..
45: "호환되는 모든 타입"을 받아들이는 데는 멤버 함수 템플릿이 직방! 포인터에는 스마트 포인터로 대신할 수 없는 특징이 있다. 그 중 하나가 암시적 변환을 지원한다는 점이다. class Top {}; class Middle : public Top {}; class Bottom : public Middle {}; Top* pt1 = new Middle; Top* pt2 = new Bottom; const Top* pct2 = pt1; 이런 식의 타입 변환을 사용자 정의 스마트 포인터를 써서 흉내 내려면 무척 까다롭다. template class SmartPtr { public: explicit SmartPtr(T* realPtr); }; SmartPtr pt1 = SmartPtr(new Middle)..

문제 풀이 두 포인터, 문자열 문제이다. 두포인터와 재귀 함수로 해당 문자열이 팰린드롬인지 판별한다. 현재 start와 end에서의 문자가 맞지 않다면 start + 1과 end까지와 start부터 end - 1까지 문자열을 확인하도록 함수를 재귀한다. 이미 문자가 맞지 않은 상태에서, 다시 start와 end의 문자가 맞지 않다면 회문이나 유사회문이 아니다. 코드 #include #include #include using namespace std; // 투 포인터로 양 옆에서 접근하며 팰린드롬을 체크한다. int solution(string current, int start, int end, int in_diff_count) { int diff_count = in_diff_count; while (st..
보호되어 있는 글입니다.