Search
Duplicate
📗

C++의 STL과 응용

자세한 사항들은 아래 링크에서 배우시면 됩니다.

vector

동적 배열이다. vector뒤에 원소를 넣고 빼는 연산에 특화되어 있다. 대괄호에 대해서 Overloading이 되어 있어서 index로 접근이 가능하지만, for 문에 쓸 때와 같이 순회를 할 때는 iterator를 쓰는 것이 권장된다. 2차원 배열과 같이 쓰기 위해 vector의 vector를 쓰는 경우 (>>를 쓸 때) >과 > 사이에 스페이스가 있어야 한다. 그렇지 않으면 비트 연산 (Shfiting) >>으로 해석해서 컴파일 에러가 생길 수도 있다.
#include <cstdio> #include <vector> using namespace std; // int외의 다른 것들도 가능. // double,long long, struct 혹은 vector마저도 가능. vector<int> vt; int main(void){ int sizeOfArr,tmp; scanf("%d",&sizeOfArr); for(int i=0;i<sizeOfArr;i++){ scanf("%d",&tmp); // vector에 저장(제일 뒤에 저장됨) vt.push_back(tmp); } // iter앞에 *이 붙어있는 점에 주의하자 for(vector<int>::iterator iter=vt.begin();iter!=vt.end();iter++)//iterator가 end에 도달하면 이미 모든 원소 탐색을 한 것이다. printf("%d ",*iter); return 0; }
C++
복사

queue

이름에서부터 알 수 있듯이 queue이다. FIFO 연산에 특화되어 있다.
#include <cstdio> #include <queue> using namespace std; queue<int> qu; int main(void){ int sizeOfArr,tmp; scanf("%d",&sizeOfArr); for(int i=0;i<sizeOfArr;i++){ scanf("%d",&tmp); // queue에 저장(제일 뒤에 저장됨) qu.push(tmp); } // 큐가 빌때까지 while(!qu.empty()){ // 제일 앞에 있는 원소 출력 printf("%d ",qu.front()); // 앞에 있는 원소 제거 pop의 리턴 값이 원소가 아님에 주의 qu.pop(); } return 0; }
C++
복사

pair

2개의 원소를 합쳐 하나의 원소로 나타낸다. pair가 강력해지는 부분은 비교 연산이다. 비교 연산을 수행할 시 우선적으로 앞의 원소를 비교하고 그 후에 뒤의 원소를 비교한다.
예를 들어,
pair<int, pair<double, float> >
C++
복사
위 자료형을 가지는 원소 a,b가 있다고 해보자. a의 int를 a_1, double을 a_2, float을 a_3 그리고 이에 상응하게 b의 원소 b_1,b_2,b_3라고 부르자. 그러면 우선 a_1과 b_1을 비교하여 같지 않으면 그 결과를 리턴한다. 즉 a_1< b_1 이면 a < b, a_1 > b_1 이면 a > b 이다. a_1과 b_1이 같으면 pair를 비교한다. 그런데 pair 연산은 왼쪽 원소부터 비교를 시작하므로 double을 비교하기 시작한다. 결국 a_2와 b_2를 비교하여 같지 않으면 그 결과를 리턴한다. a_2와 b_2가 같으면 a_3와 b_3를 비교하며 이 마저도 같을 때 같다라는 연산이 성립한다.
또한 pair에 대한 객체를 생성할 때는 직접 선언하여 만들 수도 있지만, make_pair 함수를 이용하는 것이 권장된다. 그 이유는 아래와 같이, make_pair를 이용 시에는 전달할 요소에 대한 타입을 명시하지 않고 짧은 구문을 통해 이용할 수 있기 때문이다. (C++ 11 모던 영역에 와서는 중괄호로 명시를 해주는 것으로 타입 명시 없이 이용할 수는 있게 되었으나 여전히 make_pair 이용을 권장한다. 컴파일러 의존성이 높아지는 코드가 될 수 있다.)
pair <int, int> one; pair <int, int> two; pair <int, int> three; one = make_pair(10, 20); // 암시적 형변환 덕에 오류 없이 수행 two = make_pair(10.5, 'A'); three = pair<int, int>(10, 20);
C++
복사
위 코드에서 make_pair가 타입을 유추하는 것은 아래와 같은 일종의 Template 코드를 통해서 이뤄진다.
template<class T1, class T2> std::pair<T1, T2> make_pair(T1 t1, T2 t2) { return std::pair<T1, T2>(t1, t2); }
C++
복사
#include <cstdio> #include <vector> // pair있는 header #include <utility> using namespace std; // vector나 queue등에 넣을 수 있음. vector<pair<int,int> > vt; int main(void){ int a1,a2; for(int i=0;i<10;i++){ scanf("%d %d",&a1,&a2); // make_pair로 pair를 만듦 vt.push_back(make_pair(a1,a2)); } // 첫번째 원소는 first 두번째 원소는 second로 접근. // vector의 iterator로 접근해서 포인터 접근함. for(vector<pair<int,int> >::iterator iter=vt.begin();iter!=vt.end();iter++) printf("%d %d\n",iter->first,iter->second); return 0; }
C++
복사

sort

말 그대로 정렬을 의미한다. 시간 복잡도는 O(nlogn)이다. 기본적으로 오름차순으로 정렬된다. sort함수에 다른 인자를 넣어 내림차순을 구현할 수도 있지만 코딩 테스트에서는 보통 원소에 -를 곱해 내림차순을 구현한다.
#include <cstdio> #include <vector> // sort있는 header #include <algorithm> using namespace std; vector<int> vt; int main(void){ int sizeOfArr,tmp; scanf("%d",&sizeOfArr); for(int i=0;i<sizeOfArr;i++){ scanf("%d",&tmp); vt.push_back(tmp); } // vector vt 정렬 sort(vt.begin(),vt.end()); // iter앞에 *이 붙어있는 점에 주의하자 // iterator가 end에 도달하면 이미 모든 원소 탐색을 한 것이다. for(vector<int>::iterator iter=vt.begin();iter!=vt.end();iter++) printf("%d ",*iter); return 0; }
C++
복사

map

Key와 Value를 mapping해주는 STL이다. Key가 0부터 연속된 양의 정수라면 배열과 다를 바 없다. 그러나 문제를 풀다보면 문자열끼리 대응시키거나 정수가 아닌 타입과 mapping 시켜야 하는 경우가 있다. 그럴 때 이 STL을 쓰면 편하다.
#include <cstdio> #include <map> #include <string> using namespace std; map<string,double> studentScore; int main(void){ int sizeOfInput; char str_c[50]; scanf("%d",&sizeOfInput); for(int i=0;i<sizeOfInput;i++){ double score; scanf("%s %lf",str_c,&score); string str = str_c; // map에 넣을때는 insert를 사용해도 되고 // studentScore[str]=score;//대괄호[]를 이용하여 배열처럼 사용할 수도 있습니다. studentScore.insert(make_pair(str,score)); } scanf("%s",str_c); string str = str_c; // Key가 들어온 적이 없는지 확인하기 위해 이렇게 접근합니다. if(studentScore.find(str)==studentScore.end()) printf("Failed to find\n"); else // 무조건 들어왔다는 확신이 있다면 find한 값이 end()와 같은지 비교하지 않고 바로 대괄호로 접근해도 됩니다. printf("Score is %lf\n",studentScore[str]); return 0; }
C++
복사

stack

FILO 연산에 특화되어 있는 STL이다. 잘 생각해보면 vector STL을 stack처럼 사용할 수 있기 때문에 상대적으로 적게 쓰인다.

set

수학에서 집합은 중복 원소를 허용하지 않는다. 이와 유사하게 set STL은 중복된 원소가 들어올 시 무시한다. 특정 원소의 존재 여부를 확인할 때 사용하기 좋은 STL이다.
#include <cstdio> #include <set> #include <string> using namespace std; set<string> studentName; int main(void){ int sizeOfInput; char str_c[50]; scanf("%d",&sizeOfInput); for(int i=0;i<sizeOfInput;i++){ scanf("%s",str_c); string str = str_c; // set에 넣을때는 insert를 사용하면 됩니다. studentName.insert(str); } scanf("%s",str_c); string str = str_c; // set에 원소가 존재하는지 확인하기 위해 이렇게 접근합니다. if(studentName.find(str)==studentName.end()) printf("Failed to find\n"); else printf("Success to find\n"); return 0; }
C++
복사

tuple

pair를 확장한 자료구조로써, 다수의 원소를 합쳐 하나의 원소로 나타낸다. (여러 타입을 묶을 수 있다고 보면 된다.) C++11부터 지원한다.
#include <cstdio> #include <tuple> #include <vector> using namespace std; vector<tuple<int,int,int> > coordinate; int main(void){ for(int i=0;i<10;i++){ int x,y,z; scanf("%d %d %d",&x,&y,&z); // make_tuple로 tuple를 만듦 coordinate.push_back(make_tuple(x,y,z)); } // get을 사용하여 원소에 접근 for(vector<tuple<int,int,int> >::iterator iter=coordinate.begin();iter!=coordinate.end();iter++) printf("%d %d %d\n",get<0>(*iter),get<1>(*iter),get<2>(*iter)); return 0; }
C++
복사

priority_queue

우선순위 queue이다. 비교연산을 통해 가장 큰 값부터 반환한다.
#include <cstdio> #include <queue> using namespace std; priority_queue<int> qu; int main(void){ int sizeOfArr,tmp; scanf("%d",&sizeOfArr); for(int i=0;i<sizeOfArr;i++){ scanf("%d",&tmp); // queue에 저장 qu.push(tmp); } // 큐가 빌때까지 while(!qu.empty()){ // 제일 큰 원소 출력 printf("%d ",qu.top()); // 앞에 있는 원소 제거 pop의 리턴 값이 원소가 아님에 주의 qu.pop(); } return 0; }
C++
복사

binary_search

이분 탐색할 때 사용한다. 시간 복잡도는 O(logn)이다. 호출하기 전에 정렬되어 있어야한다.
#include<cstdio> #include<vector> // binary_search있는 header #include<algorithm> using namespace std; vector<int> vt; int main(void){ int sizeOfArr,tmp; scanf("%d",&sizeOfArr); for(int i=0;i<sizeOfArr;i++){ scanf("%d",&tmp); vt.push_back(tmp); } //vector vt 정렬 sort(vt.begin(),vt.end()); for(int i=0;i<sizeOfArr;i++){ scanf("%d",&tmp); if(binary_search(vt.begin(),vt.end(),tmp)) printf("Exists\n"); else printf("There is no such element\n"); } return 0; }
C++
복사