[C++] vector 클래스

Doorbals·2023년 1월 3일
0

CPP

목록 보기
4/16

1. vector 클래스

  • 동적 배열 구조를 C++로 구현한 것으로, 맨 끝에서만 삽입 및 삭제가 일어나는 구조
  • 벡터에 원소가 삽입되고 삭제됨에 따라 동적으로 크기가 변하고 메모리가 연속적이다.
  • 중간 데이터를 삭제하기 위해서는 erase 함수를 사용할 수 있지만, 벡터의 맨 끝 이외에서의 삽입 및 삭제의 경우 비효율적이다. -> 삭제가 빈번하면 연결리스트(Linked List)를 사용하는 것이 효율적.

2. vector의 생성 방법

1) vector의 크기 지정하지 않고 생성

	vector<int> v;`	// 벡터 v 생성

2) vector의 크기 지정하고 생성

	vector<int> v(10);	// 크기 10의 벡터 생성

3) vector의 크기 지정하고 모두 같은 값으로 초기화

	vector<int> v(10, 1); // 크기 10의 벡터에 전부 1로 초기화

4) vector의 원소를 지정하여 생성

	vector<int> v = {1, 2, 3};

3. vector 클래스 멤버 함수

1) Iterator (반복자)

: Iterator를 활용해 vector의 원소에 접근 가능

  • v.begin() : 벡터의 첫 번째 원소를 가리키는 iterator
  • v.end() : 벡터의 마지막 원소 다음을 가리키는 iterator

❗이터레이터

  • 컨테이너에 저장되어 있는 원소들을 하나씩 접근할 수 있게 해줌.

  • 모든 컨테이너들이 같은 방법으로 반복자 사용 가능.

  • 각 타입에 ::iterator 또는 ::const_iterator를 붙여 사용.

    • vector 컨테이너의 반복자 itr : vector<int>::iterator itr;
    • vector 컨테이너의 const 반복자 itr : vector<int>::const_iterator itr;
    • iterator와 const_iterator의 차이는 반복자가 가리키는 원소 값의 변경 가능 여부
      • const_iterator는 *itr = 3과 같이 간접 참조로 반복자가 가리키는 원소 변경 불가능
  • 포인터와 비슷하게 사용

    • vector<int> v = {1, 2, 3}; / vector<int>::iterator itr 이 존재
    • itr = v.begin() + 1;로 이터레이터 초기화 후 *itr로 간접 참조시 2가 반환됨

vector에서 이터레이터 사용 예시

	vector<int> v = {1, 2, 3, 4, 5};
	
	for (auto itr = v.begin(); itr != v.end(); itr++) // auto가 vector<int>::iterator로 추론함.
		cout << *itr << " ";
        
        
   	출력 결과 : 1 2 3 4 5

2) 일반 함수

a. 초기화

  • v.assign(n) : n개의 원소를 0으로 초기화
  • v.assign(n, m) : n개의 원소를 m으로 초기화

b. 원소 접근

  • v.front() : 첫 번째 원소 반환
  • v.back() : 마지막 원소 반환
  • v.at(n) / v[n] : n번째 원소 반환

c. 원소 삽입 / 삭제

  • v.push_back(n) : 벡터의 맨 뒤에 n 삽입
  • v.pop_back(n) : 맨 뒤 원소 삭제
  • v.insert(iterator, n) : iterator가 가리키는 위치에 n 삽입. 뒤에 있는 원소들은 한 자리씩 밀림.

d. 벡터 크기 관련

  • v.size() : 벡터의 원소 개수 반환

  • v.capacity() : 벡터가 할당된 메모리 크기 반환

  • v.reserve(n) : 벡터의 메모리 크기를 n으로 미리 할당.

    • 늘어난 공간은 비어있음.
    • size는 그대로 / capacity만 n으로.
    • 현재 공간보다 더 작게 줄일 수 X
	vector<int> v = { 1, 2, 3 };
	
	v.reserve(2);	// 효과 없음. 오류는 발생하지 않음.

	cout << "현재보다 작게 줄였을 때 size : " << v.size() << endl;
	cout << "현재보다 작게 줄였을 때 capacity : " << v.capacity() << endl << endl;

	v.reserve(4);	// size는 그대로, capacity는 증가

	cout << "현재보다 크게 늘렸을 때 size : " << v.size() << endl;
	cout << "현재보다 크게 늘렸을 때 capacity : "  << v.capacity() << endl;

  • v.resize(n) : 벡터의 메모리 크기를 n으로 할당.

    • 늘어난 공간은 0으로 초기화
    • size를 n으로 / 현재 공간보다 늘릴 경우 capacity도 n으로, 줄일 경우 capacity는 그대로.
    • 현재 공간보다 더 작게 줄일 수 O
	vector<int> v = { 1, 2, 3 };
	
	v.resize(2);	// size 감소, capacity는 그대로

	cout << "현재보다 작게 줄였을 때 size : " << v.size() << endl;
	cout << "현재보다 작게 줄였을 때 capacity : " << v.capacity() << endl << endl;

	v.resize(4);	// size 증가, capacity도 증가

	cout << "현재보다 크게 늘렸을 때 size : " << v.size() << endl;
	cout << "현재보다 크게 늘렸을 때 capacity : "  << v.capacity() << endl;

e. 원소 삭제

  • v.clear() : 전체 원소 삭제
  • v.erase(iterator) : iterator가 가리키는 원소 삭제. size만 변화, capacity는 그대로.

4. vector의 동적 배열 특성

: 동적 배열은 크기가 고정되지 않은 배열로서, 원소가 추가되거나 삭제될 때마다 메모리를 할당하거나 감소하는 작업이 일어난다. 하지만 이렇게 하나가 추가될 때마다 매번 작업을 수행하게 되면 비용이 많이 들기 때문에 미리 일정 배율로 공간을 할당해두게 된다.

벡터에서도 원소의 size와 capacity가 정비례로 증가하지 않고 일정 범위마다 일정 배율로 증가하는 것을 확인할 수 있다.

[예시 코드]

	vector<int> v;
	
	for (int i = 2; i < 50; i++)
	{
		cout << "size :" << v.size() << " / ";
		cout << "capacity : " << v.capacity() << endl;

		v.resize(i);
	}

profile
게임 클라이언트 개발자 지망생의 TIL

0개의 댓글