알고리즘/알고리즘 이론

[C++] 코딩테스트 준비를 위한 C++ : 표준라이브러리(stl)

excited-hyun 2021. 1. 29. 00:29
반응형

며칠 동안 c언어로 계속 코딩을 하다 보니 c++을 얼른 공부해서 표준 라이브러리를 사용해야겠다는 생각이 너무 절실했다.
같은 코드를 짜도 c++로 짜는 경우와 c로 짜는 경우 코드 길이의 차이가 어마어마하다ㅠㅠ
코딩 테스트에는 객체까지 사용할 필요는 없어 보여서 일단 절실한 표준 라이브러리 사용을 먼저 익히기로 하였다!

입출력

입출력의 경우엔 c에서 사용하던 scanf(), printf()를 그냥 그대로 사용할 것이다.
평소 c++의 입출력을 사용할 때 처럼 개행에 endl을 사용하면 출력 버퍼를 비우는 시간까지 소요되기 때문이다.
c의 입출력 사용을 위해서는 <stdio.h> 또는 <cstdio> 헤더를 추가해야한다.

STL

c를 사용하지 않고 c++을 사용함으로써 얻을 수 있는 가장 큰 이점은 아무래도 STL(표준 라이브러리)를 사용할 수 있다는 점이다.
알고리즘 문제들을 푸는 데에 자주 쓰이는 것은 pair, vector, queue, stack, set, map, priority queue 이 정도라고 보면 된다.

Pair

두 가지 자료형을 하나의 쌍으로 묶을 수 있게 해 준다.
기본적으로는 utility 헤더에서 제공되는 것이나, vector나 algorithm 헤더 파일에 포함되어 있기 때문에 utility를 include 해줄 필요는 없다.
첫 번째 데이터는 first, 두 번째 데이터는 second로 접근한다.
p = make_pair(f, s)로 한 번에 대입하는 것도 가능하다.

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

int main(int argc, const char * argv[]) {
    pair<int, char> p;
    
    scanf("%d %c", &p.first, &p.second);
    printf("%d %c\n", p.first, p.second);
    
    p.first = 1;
    p.second = 'a';
    printf("%d %c\n", p.first, p.second);
    
    p=make_pair(3, 'b');
    printf("%d %c\n", p.first, p.second);
    
}

scanf 입력으로는 7과 'c'를 입력해주었다.
결과가 잘 나오는 것을 알 수 있다.

using namespace std; 는 안 쓰는 게 좋다는데 일단은 그냥 사용하겠다.

Vector

크기가 가변적인 배열이다. c의 array의 경우엔 크기가 정적이기 때문에 크기 변경을 할 수가 없다.
그러나 vector의 경우엔 동적으로 할당되어 크기를 자유자재로 변경할 수 있다.
vector 헤더파일을 추가하여 사용한다.

front() : 첫 번째 원소
back() : 마지막 원소
begin() : 첫번째 위치
end() : 마지막의 다음 위치
push_back() : 마지막에 데이터 추가
pop_back() : 마지막에서 데이터 뽑기
size() : 원소의 개수
clear() : 비우기

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

int main(int argc, const char * argv[]) {
    vector<int> v1 = {1, 2, 3};
    vector<pair<int, char>> v2;
    int a, b;
    char c, d;
    
    v1.push_back(5);
    v1.push_back(6);
    for (int i=0; i < v1.size(); i++) {
        printf("%d ", v1[i]);
        
    }
    printf("\n");
    
    a = v1.front();
    b = v1.back();
    printf("front: %d, back: %d\n", a, b);
    v1.pop_back();
    for (int i=0; i < v1.size(); i++) {
        printf("%d ", v1[i]);
        
    }
    printf("\n"); //vector에 pair도 들어간다!
    
    v2.push_back(make_pair(1, 'a'));
    v2.push_back(make_pair(2, 'b'));
    v2.push_back(make_pair(3, 'c'));
    for (int i=0; i < v2.size(); i++) {
        printf("<%d %c> ", v2[i].first, v2[i].second);
        
    }
    printf("\n");
    
    a = v2.front().first;
    c = v2.front().second;
    b = v2.back().first;
    d = v2.back().second;
    printf("front: <%d %c>\n", a, c);
    printf("back: <%d %c>\n", b, d);
    v2.clear();
    
}

 

반응형

 

Queue

FIFO(First In First Out)인 자료구조이다.
queue 헤더파일을 추가하여 사용한다.
BFS에 매우매우 유용하다.

push() : 마지막에 데이터 추가
pop() : 맨앞에서 데이터 뽑기
front() : 첫 번째 원소
back() : 마지막 원소
size() : queue의 크기
empty() : queue가 비어있는지 확인

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;

int main(int argc, const char * argv[]) {
    queue<int> q1;
    queue<pair<int, char>> q2;
    int a, b;
    int n;
    char c, d;
    
    q1.push(1);
    q1.push(2);
    q1.push(3);
    q1.push(4);
    q1.push(5);
    q1.push(6);
    a = q1.front();
    b = q1.back();
    n = q1.size();
    
    for(int i=0; i<n; i++){
        printf("%d ", q1.front()); q1.pop();
        
    }
    printf("\n");
    
    printf("front: %d, back: %d\n", a, b);
    q2.push(make_pair(1, 'a'));
    q2.push(make_pair(2, 'b'));
    q2.push(make_pair(3, 'c'));
    q2.push(make_pair(4, 'd'));
    q2.push(make_pair(5, 'e'));
    
    a = q2.front().first;
    c = q2.front().second;
    b = q2.back().first;
    d = q2.back().second;
    n = q2.size();
    for(int i=0; i<n; i++){
        printf("<%d %c> ", q2.front().first, q2.front().second);
        q2.pop();
        
    }
    printf("\n");
    printf("front: <%d %c>, back: <%d %c>\n", a, c, b, d);
    
}

 

 

Stack

LIFO(Last In First Out)인 자료구조이다.
stack 헤더파일을 추가하여 사용한다.

push() : top에 데이터 추가
pop() : top에서 데이터 뽑기
top() : top에 있는 원소
size() : stack의 크기
empty() : stack이 비어있는지 확인

#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;

int main(int argc, const char * argv[]) {
    stack<int> s1;
    stack<pair<int, char>> s2;
    int a, b;
    int n;
    char c, d;
    
    s1.push(1); s1.push(2); s1.push(3);
    s1.push(4); s1.push(5); s1.push(6);
    
    a = s1.top();
    n = s1.size();
    
    for(int i=0; i<n; i++){
        printf("%d ", s1.top()); s1.pop();
        
    }
    printf("\n"); printf("top: %d\n", a);
    
    s2.push(make_pair(1, 'a'));
    s2.push(make_pair(2, 'b'));
    s2.push(make_pair(3, 'c'));
    s2.push(make_pair(4, 'd'));
    s2.push(make_pair(5, 'e'));
    
    a = s2.top().first;
    c = s2.top().second;
    n = s2.size();
    for(int i=0; i<n; i++){
        printf("<%d %c> ", s2.top().first, s2.top().second);
        s2.pop();
        
    }
    printf("\n");
    printf("top: <%d %c>\n", a, c);
    
}

 

Set

Associative 컨테이너이다.
Key라 불리는 원소들의 집합으로 이루어 진다.
Key값은 중복이 허용되지 않으며 insert()를 통해 삽입할 수 있고 자동으로 오름차순 정렬된다.
set 헤더파일을 추가하여 사용한다.

insert(k) : 원소 k 삽입
begin() : 맨 첫번째 원소를 가리키는 iterator를 반환
end() : 맨 마지막 원소를 가리키는 iterator를 반환
find(k) : 원소 k를 가리키는 iterator를 반환
size() : set의 원소 수
empty() : 비어있는지 확인

#include <iostream>
#include <cstdio>
#include <set>
using namespace std;

int main(int argc, const char * argv[]) {
    set<int> s1;
    s1.insert(1); s1.insert(2); s1.insert(6);
    s1.insert(5); s1.insert(4); s1.insert(3);
    
    set<int>::iterator it;
    
    for (it = s1.begin(); it != s1.end(); it++) {
        printf("%d ", *it);
        
    }
    printf("\n");
    
    it = s1.find(7);
    printf("%d\n", *it);
    
    it = s1.find(6);
    printf("%d\n", *it);
    
}

 

 

728x90

 

Map

Associative 컨테이너이다.
set은 원소로 key만을 저장하지만 map은 <key, value>의 쌍으로 저장한다.
map역시 key 중복이 허용되지 않으며 insert()를 통해 삽입할 수 있고 자동으로 오름차순 정렬된다.
map은 [] 연산자가 제공되어 key에 해당하는 원소의 value에 바로 접근할 수 있다.

insert(make_pair(k, v)) : 원소를 key와 value의 pair로 삽입
erase(k): key값 k를 갖는 원소를 삭제
begin() : 맨 첫번째 원소를 가리키는 iterator를 반환
end() : 맨 마지막 원소를 가리키는 iterator를 반환
find(k) : key값 k에 해당하는 iterator를 반환
size() : map의 원소 수
empty() : 비어있는지 확인

#include <iostream>
#include <cstdio>
#include <map>

using namespace std;

int main(int argc, const char * argv[]) {
    map<char, int> m1;
    m1.insert(make_pair('a', 1)); m1.insert(make_pair('e', 5));
    m1.insert(make_pair('c', 3)); m1.insert(make_pair('d', 4));
    m1.insert(make_pair('b', 2));
    
    m1['e'] = 6;
    m1['f'] = 7;
    
    map<char, int>::iterator it;
    for (it = m1.begin(); it != m1.end(); it++) {
        printf("<%c %d> ", (*it).first, (*it).second);
        
    }
    printf("\n");
    it = m1.find('c');
    printf("%d\n", (*it).second);
    it = m1.find('d');
    printf("%d\n", (*it).second);
    m1.erase('a');
    m1.erase('c');
    
    for (it = m1.begin(); it != m1.end(); it++) {
        printf("<%c %d> ", (*it).first, (*it).second);
        
    } printf("\n");
    
}

 

Priority queue

우선순위 queue를 구현한 것이다.
queue 헤더파일을 추가하여 사용한다.

push() : top에 데이터 추가
pop() : top에서 데이터 뽑기
top() : top에 있는 원소
size() : priority queue의 크기
empty() : priority queue가 비어있는지 확인

#include <iostream>
#include <cstdio>
#include <queue>

using namespace std;

int main(int argc, const char * argv[]) {
    priority_queue< int, vector<int>, less<int> > q;
    int n;
    q.push(3); q.push(2);
    q.push(5); q.push(4);
    q.push(1); q.push(6);
    
    printf("top: %d\n", q.top());
    n = q.size();
    
    for(int i=0; i<n; i++){
        printf("%d ", q.top());
        q.pop();
        
    }
    printf("\n");
    
}

 

728x90
반응형