CS/C++

뇌를 자극하는 C++ STL : 6장. 시퀀스 컨테이너

샤아이인 2022. 1. 18.

내돈내고 내가 공부한것을 올리며, 중요한 단원은 저 자신도 곱씹어 볼겸 가겹게 포스팅 하겠습니다.

1) 6장. 시퀀스 컨테이너

본격적인 STL의 시작이다. 이번단원에서는 시퀀스 컨테이너에 대하여 배웠다.

 

Vector

vector는 임의 접근 반복자를 지원하는 배열 기반 컨테이너이다. 배열 기반의 컨테이너이므로 원소가 하나의 메모리 블록에 할당된다.

 

Capacity 는 다른 컨테이너들에는 없으며 오직 vector만이 갖고있다.

 

clear() 맴버함수를 통하여 원소를 제거한후에는 size는 0이 되지만, capacity는 그대로 유지된다.

메모리가 부족한 상황이라면 이는 비효율적이다. 따라서 할당된 메모리를 모두 제거하는 방법이 없을까?

capacity를 0으로 만드는 함수는 존재하지 않지만 C++에서 권장하는 swap 방법이 있다.

 

swap()을 이용하여 임시로 생성한(기본 생성자에 의해 size, capacity가 0인) 컨테이너 객체와 capacity를 0으로 만들고자 하는 컨테이너 객체를 서로 swap하는 방법을 사용한다. 다음 코드를 확인해 보자.

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

int main()
{
	vector<int> v(5);

	cout << "size: " << v.size() << " capacity: " << v.capacity() << endl;

	v[0] = 10;
	v[1] = 20;
	v[2] = 30;
	v[3] = 40;
	v[4] = 50;

	vector<int>().swap(v);

	cout << "size: " << v.size() << " capacity: " << v.capacity() << endl;

	return 0;
}
 

결과는 다음과 같다.

원하던데로 capacity를 0으로 만들었다.

 

Const와 반복자

- vector<int>::iterator iter: iter는 다음 원소로 이동이 가능, 원소의 변경이 가능한 반복자.

- vector<int>::const_iterator citer: citer는 다음 원소로 이동 가능, 원소의 변경이 불가능한 반복자.

- const vector<int>::iterator iter_const: iter_const는 다음 원소로 이동이 불가능, 원소의 변경이 가능한 반복자.

- const vector<int>::const_iterator citer_const: citer_const는 다음 원소로 이동이 불가능, 원소의 변경이 불가능한 반복자.

 

Deque

deque는 vector와 유사한 컨테이너이다. 하지만 하나의 메모리 블록을 사용하는 vector와는 달리 deque는 여러개의 메모리 블록을 할당하고 사용자에게는 하나의 블록처럼 보이게 하는 방식을 취한다. 다음 코드를 통하여 확인해보자.

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

int main()
{
	vector<int> v(5, 7);
	deque<int> dq(5, 7);

	v.push_back(8);
	dq.push_back(8);

	cout << "vector> ";
	for (vector<int>::size_type i = 0; i < v.size(); i++)
		cout << v[i] << " ";
	cout << endl;

	cout << "deque> ";
	for (deque<int>::size_type i = 0; i < dq.size(); i++)
		cout << dq[i] << " ";
	cout << endl;

	return 0;
}
 

결과는 다음과 같다.

딱 결과만 보면 똑같이 작동하는 것 같지만, 내부적으로 메모리를 사용하는 방식이 다르다.

v는 메모리 블록을 재할당 하고 이전의 것들을 복사해서 원소를 추가하지만, deque는 새로운 메모리 블록을 추가하여 새로운 원소를 추가한다. 복사과정이 필요가 없다!

 

List

list의 가장 큰 특징 중 하나는 순차열 중간에 원소를 삽입, 제거 하더라도 상수시간 복잡도의 수행 성능을 보인다.

 

list는 반복자를 사용하여 원소를 제거하는 erase()말고도 원소의 값을 이용하여 제거하는 remove()또한 존재한다.

컨테이너의 모든 원소를 순차적으로 검색하여 제거한다. 다음 코드를 통하여 확인할 수 있다.

#include <iostream>
#include <list>
using namespace std;

int main()
{
	list<int> li;

	li.push_back(7);
	li.push_back(20);
	li.push_back(7);
	li.push_back(30);
	li.push_back(7);
	li.push_back(40);
	li.push_back(7);

	for (list<int>::iterator iter = li.begin(); iter != li.end(); iter++)
		cout << *iter << " ";
	cout << endl;

	li.remove(7);

	for (list<int>::iterator iter = li.begin(); iter != li.end(); iter++)
		cout << *iter << " ";
	cout << endl;

	return 0;
}
 

결과로는 다음과 같다.

유일하게 list만이 remove()를 갖는다.
 

2) 나의 현황

이번 쳅터는 100페이지 정도 되서 양이 좀 많았다. 다시한번 복습해두고 싶다.

이글의 모든 사진과 내용의 출처는 공동환 님께 있습니다.

댓글