반응형

LIFO 문맥에서 동작하기 위해 설계된 컨테이너 어댑터

stack의 top으로 알려진 container의 back에서 push와 pop

멤버 함수

생성

#include <iostream>
#include <stack>
#include <vector>
#include <deque>

using namespace std;

int main(){
    deque<int> deq(3, 100);
    vector<int> vc(2, 200);

    stack<int> first;    // 빈 스택
    stack<int> second(deq);     // deque를 복사하여 초기화
    stack<int, vector<int>> third;
    stack<int, vector<int>> fourth(vc);
}


용량

  • empty()
  • size()


제어

  • top()
  • push()
  • pop()
  • emplace() * C++11
  • swap() * C++11
#include <iostream>
#include <stack>

using namespace std;

int main(){
    stack<int> st;
    int sum = 0;

    for(int i = 1; i <= 10; ++i)
        st.push(i);
    cout << st.size() << endl;
    // 10

    while(!st.empty()){
        sum+= st.top();
        st.pop();
    }

    cout << sum << endl;
    // 55
}

반응형

'C++' 카테고리의 다른 글

[C++] cout 부동소수점 다루기  (0) 2020.11.20
[C++] STL - deque  (0) 2020.11.13
[C++] STL - vector  (0) 2020.10.28
[C++] 반복자  (0) 2020.10.27
[C++] STL  (0) 2020.10.27
반응형

시퀀스 컨테이너

동적 배열

요소가 추가되거나 삭제될 때마다 자동으로 메모리를 재할당하여 크기를 동적으로 변경

멤버 함수

생성

#include <vector>

using namespace std;

int main(){    
    vector<int> first;    // 빈 벡터
    vector<int> second(4, 100);    // 4개의 int(값 100)
    vector<int> third(second.begin(), second.end());    // 반복자 사용
    vector<int> fourth(third);    // 벡터 복사

    int myints[] = {1, 2, 3, 4};
    vector<int> fifth(myints, myints + sizeof(myints)/sizeof(int));    // 반복자 사용2(배열)

    return 0;
}

반복자

  • begin() / end()
  • rbegin() / rend()
  • cbegin() / cend() : const * C++11
  • crbegin() / crend() * C++11
#include <iostream>
#include <vector>

using namespace std;

int main(){
    vector<int> vc;
    for(int i = 1; i <= 5; ++i)
        vc.push_back(i);

    for(vector<int>::iterator it = vc.begin(); it != vc.end(); ++it)
        cout<<*it<<' ';
    cout<<'\n';
    // 1 2 3 4 5
    for(vector<int>::reverse_iterator rit = vc.rbegin(); it != vc.rend(); ++rit)
        cout<<*rit<<' ';
    cout<<'\n';
    // 5 4 3 2 1

    return 0;
}

용량

  • size()
  • max_size()
  • capacity()
  • resize()
  • empty()
  • reserve() : capacity 변경
  • shrink_to_fit() * C++11
#include <iostream>
#include <vector>

using namespace std;

int main(){
    vector<int> vc;
    cout << vc.size() << endl;
    cout << vc.capacity() << endl;
    cout << vc.max_size() << endl;
    // 0
    // 0
    // 536870911

    for(int i = 1; i <= 5; ++i)
        vc.push_back(i);
    cout << vc.size() << endl;
    cout << vc.capacity() << endl;
    cout << vc.max_size() << endl;
    // 5 {1, 2, 3, 4, 5}
    // 8
    // 536870911

    vc.insert(vc.end(), 10, 100);
    cout << vc.size() << endl;
    cout << vc.capacity() << endl;
    cout << vc.max_size() << endl;
    // 15 {1, 2, 3, 4, 5, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}
    // 15
    // 536870911

    vc.pop_back();
    cout << vc.size() << endl;
    cout << vc.capacity() << endl;
    cout << vc.max_size() << endl;
    // 14 {1, 2, 3, 4, 5, 100, 100, 100, 100, 100, 100, 100, 100, 100}
    // 15
    // 536870911

    return 0;
}
#include <iostream>
#include <vector>

using namespace std;

int main(){
    vector<int> vc;
    for(int i = 1; i < 10; ++i)
        vc.push_back(i);
    // 1 2 3 4 5 6 7 8 9

    vc.resize(5);
    // 1 2 3 4 5
    vc.resize(8, 100);
    // 1 2 3 4 5 100 100 100
    vc.resize(10);
    // 1 2 3 4 5 100 100 100 0 0

    return 0;
}
#include <iostream>
#include <vector>

using namespace std;

int main(){
    vector<int> vc;
    int sum = 0;

    for(int i = 1; i <= 10; ++i)
        vc.push_back(i);

    while(!vc.empty()){
        sum += vc.back();
        vc.pop_back();
    }

    cout << sum << endl;
    // 55

    return 0;
}
#include <iostream>
#include <vector>

using namespace std;

int main(){
    vector<int> vc(100);
    cout << vc.capacity() << endl;
    // 100
    vc.resize(10);
    cout << vc.capacity() << endl;
    // 100
    vc.shrink_to_fit();
    cout << vc.capacity() << endl;
    // 10

    return 0;
}

요소 접근

  • []
  • at()
  • front()
  • back()
  • data() * C++11
#include <iostream>
#include <vector>

using namespace std;

int main(){
    vector<int> vc(10);
    int len = vc.size();
    for(int i = 0; i < len; ++i)
        vc.at(i) = i;

    for(int i = 0; i < len; ++i)
        cout << ' ' << vc.at(i);
    cout << endl;
    // 0 1 2 3 4 5 6 7 8 9

    cout << vc.front() << endl;
    // 0
    cout << vc.back() << endl;
    // 9

    return 0;
}
#include <iostream>
#include <vector>

using namespace std;

int main(){
    vector<int> vc(5);
    int *p = vc.data();

    *p = 10;
    ++p;
    *p = 20;
    p[2] = 100;
    // 10 20 0 100 0

    return 0;
}

제어

  • assign()
  • push_back()
  • pop_back()
  • insert()
  • erase()
  • swap()
  • clear()
  • emplace() * C++11
  • emplace_back() * C++11

emplace vs insert: construct vs object

#include <iostream>
#include <vector>

using namespace std;

int main(){
    vector<int> first;
    vector<int> second;
    vector<int> third;

    first.assign(7, 100);    // 사이즈, 값
    second.assign(first.begin()+1, first.end()-1);    // 반복자, 반복자

    int arr[] = {12, 34, 56};
    third.assign(arr, arr+3);

    cout << first.size() << ' ' << second.size() << ' ' << third.size() << endl;
    // 7 5 3
}
#include <iostream>
#include <vector>

using namespace std;

int main(){
    vector<int> vc;

    for(int i = 1; i <= 5; ++i)
        vc.push_back(i);
    // 1 2 3 4 5
    vc.pop_back();
    // 1 2 3 4
}
#include <iostream>
#include <vector>

using namespace std;

int main(){
    vector<int> vc(3, 100);
    vc.insert(vc.begin(), 200);
    vc.insert(vc.begin(), 2, 300);
    // 300 300 200 100 100 100

    vector<int> vc2(2, 400);
    vc.insert(vc.begin() + 2, vc2.begin(), vc2.end());
    // 300 300 400 400 200 100 100 100

    int arr[] = {501, 502, 503};
    vc.insert(vc.begin(), arr, arr+3);
    // 501 502 503 300 300 400 400 200 100 100 100

    vc.erase(vc.begin()+5);
    // 501 502 503 300 300 400 200 100 100 100
    vc.erase(vc.begin()+3, vc.begin()+4);
    // 501 502 503 400 200 100 100 100

    return 0;
}
#include <iostream>
#include <vector>

using namespace std;

int main(){
    vector<int> vc1(3, 100);
    vector<int> vc2(5, 200);
    vc1.swap(vc2);

    vector<int>::iterator it;
    for(it = vc1.begin(); it != vc1.end(); ++it)
        cout << *it << ' ';
    cout << endl;
    for(it = vc2.begin(); it != vc2.end(); ++it)
        cout << *it << ' ';
    cout << endl;
    // 200 200 200 200 200
    // 100 100 100

    vc1.clear();
    vc1.push_back(1);
    for(it = dq1.begin(); it != dq1.end(); ++it)
        cout << *it << ' ';
       // 1

    return 0;
}

할당

  • get_allocator()
반응형

'C++' 카테고리의 다른 글

[C++] cout 부동소수점 다루기  (0) 2020.11.20
[C++] STL - deque  (0) 2020.11.13
[C++] STL - stack  (0) 2020.10.28
[C++] 반복자  (0) 2020.10.27
[C++] STL  (0) 2020.10.27
반응형

STL 컨테이너에 저장된 요소를 반복적으로 순회하여, 각각의 요소에 대한 접근을 제공하는 객체


특징

  • 가리키는 요소의 값에 접근
  • 반복자 사이의 대입 연산, 비교 연산
  • 가리키는 요소의 주변 요소로 이동

종류

  • 입력 반복자
  • 출력 반복자
  • 순항향 반복자
  • 양방향 반복자
  • 임의 접근 반복자

입력 반복자

컨테이너로부터 값을 읽는 데 사용(변경 X)

증가 연산자(++)를 사용하여 순방향으로만 이동 가능

참조 연산자(*)를 사용하여 요소 참조

ex) find()

출력 반복자

컨테이너의 값을 변경하는 데 사용(읽기 X)

증가 연산자(++)를 사용하여 순방향으로만 이동 가능

참조 연산자(*)를 사용하여 한 번 요소 변경 가능

ex) copy()

순방향 반복자

입출력 모두 가능 -> 다중 패스 알고리즘에 사용 가능

증가 연산자(++)를 사용하여 순방향으로만 이동 가능

참조 연산자(*)를 사용하여 요소를 참조하거나 변경 가능

ex) replace()

양방향 반복자

입출력 모두 가능

증감연산자(++/--)를 사용하여 양방향 이동 가능

참조 연산자(*)를 사용하여 요소를 참조하거나 변경 가능

ex) reverse()

임의 접근 반복자

양방향 반복자의 모든 기능 포함 + 일반 포인터가 하는 거의 모든 일

증감연산자(++/--)를 사용하여 양방향 이동 가능

첨자 연산자([])를 통해 임의의 요소에 접근 가능

산술 연산자(+, -)와 관계 연산자(<, <=, >, >=) 사용 가능

ex) sort()


계층

반복자는 계층적으로 분류

다양한 반복자를 사용하여 알고리즘의 적용 조건을 제한


기타 반복자

스트림 반복자

반복자 연산을 통해 알고리즘이 입출력 스트림에 쉽게 접근

입출력 스트림을 각각 입출력 반복자로 변환하는 방식으로 제공

istream_iterator, ostream_iterator 클래스 템플릿에서 제공

vector<int> vc = {1, 2, 3, 4, 5};
copy(vc.begin(), vc.end(), ostream_iterator<int>(cout));
// 12345
cout<<endl;
copy(vc.begin(), vc.end(), ostream_iterator<int>(cout));
// 1 2 3 4 5

삽입 반복자

그 요소의 위치에 새로운 값을 삽입 cf) 출력 반복자: 가리키는 요소의 값 덮어쓰기

  • insert_iterator - insert() : 해당 컨테이너의 특정 위치에 삽입, 모든 컨테이너에 사용 가능
  • back_insert_iterator - push_back(): 해당 컨테이너의 뒤쪽에 삽입, 시퀀스 컨테이너(vector, list, deque)에 사용 가능
  • front_insert_iterator - push_front(): 해당 컨테이너의 앞쪽에 삽입, list, deque에 사용 가능
list<int> ls = {10};
ls.push_back(20);
ls.push_front(30);
copy(ls.begin(), ls.end(), ostream_iterator<int>(cout, " "));
// 30 10 20

역방향 반복자

순방향 반복자와 반대 방향으로 동작하는 반복자

역방향 반복자의 증가 연산자(++)은 순방향 반복자의 역방향으로 이동

rbegin(), rend() 멤버 함수를 사용하면 자동으로 reverse_iterator 반환

list<int> ls = {10, 20, 30};
copy(ls.rbegin(), ls.rend(), ostream_iteraot<int>(cout, " "));
// 30 20 10

상수 반복자

반복자가 가리키는 값의 변경이 불가능한 반복자(이동하여 다른 요소를 가리키는 것은 가능)

const_iterator 타입

list<int> ls = {10, 20, 30};
list<int>::iterator iter;
list<int>::const_iterator citer;

iter = ls.begin();
*iter = 100;
citer = ls.end();
// *citer = 300;

for(citer = ls.begin(); citer != ls.end(); ++citer)
    cout<<*citer<<" ";
// 100 20 30
반응형

'C++' 카테고리의 다른 글

[C++] cout 부동소수점 다루기  (0) 2020.11.20
[C++] STL - deque  (0) 2020.11.13
[C++] STL - stack  (0) 2020.10.28
[C++] STL - vector  (0) 2020.10.28
[C++] STL  (0) 2020.10.27
반응형

1. STL 이란

Standard Template Library

c++을 위한 라이브러리

구성

  • 컨테이너
    • 시퀀스 컨테이너: 데이터를 선형으로 저장
    • 연관 컨테이너: 데이터를 일정 규칙에 따라 조직화하여 저장하고 관리
      • set
      • multiset
      • map
      • multimap
    • 컨테이너 어댑터: 인터페이스를 제한한 시퀀스나 연관 컨테이너의 변형, 반복자 지원 X
      • stack
      • queue
      • priority_queue
  • 반복자(Iterator)
  • 알고리즘
  • 함수자(functor)

특징

  • 제네릭 프로그래밍
  • 추상화
  • 폰 노이만 구조
  • 벨류 시멘틱스
반응형

'C++' 카테고리의 다른 글

[C++] cout 부동소수점 다루기  (0) 2020.11.20
[C++] STL - deque  (0) 2020.11.13
[C++] STL - stack  (0) 2020.10.28
[C++] STL - vector  (0) 2020.10.28
[C++] 반복자  (0) 2020.10.27

+ Recent posts