상세 컨텐츠

본문 제목

vector 벡터

자료구조&알고리즘/C++

by geminanolja 2024. 12. 14. 16:27

본문

std::vector는 C++의 **표준 템플릿 라이브러리(STL)**에서 제공하는 동적 배열 컨테이너

동적 배열: 컴파일 시에 사용해야할 요소들의 개수를 모르거나 이후 변경될 수 있다면 vector을 쓰는 것이 좋다

연속된 메모리 공간에 위치한 같은 타입의 요소들의 모음이며 숫자인덱스를 기반으로 랜덤접근이 가능하며 중복을 허용

 

탐색과 맨뒤의 요소를 삭제하거나 삽입 : O (1)

중간에 요소를 삭제 삽입하는데는 O(n)의 시간이 걸림 //만약 위치를 안하면 O(1)

 

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

int main()
{
	int a[] = { 0,2,3,4 };

	cout << "a[2] : " << a[2] << endl;

	float b[3];
	for (int i = 0; i < 3; i++)
	{
		b[i] = i + 3.2;
		cout << "b["<<i<<"] : " << b[i] << endl;
	}

	//vector를 이용한 동적 배열 생성
	vector<int> myVector{ 1,2,3,4,5 };
	vector<int> myVector2 = {10,20,30,40,50};
	vector<int> myVector3;
	myVector3 = { 100,200,300,400,500 };

	for (int i = 0; i < myVector.size(); i++)
	{
		cout << myVector[i] << endl;
		cout << myVector2[i] << endl;
		cout << myVector3[i] << endl;
	}
	/*
	//new를 이용한 동적 배열 생성
	cout << "How big is your int Attay?" << endl;
	int N;
	cin >>N;
	
	
	int* intArray = new int[N];
	for (int i = 0; i < N; i++)
	{
		intArray[i] = i;
		cout << "intAttay member values :" << intArray[i] << endl;
	}

	delete[] intArray;*/

	int* Array02 = new int[4] {0, 2, 3, 4};
	int* Array03 = new int[6] {0, 2, 3, 4};
	for (int i = 0; i < 6; i++)
	{
		cout << Array03[i] << endl;
		
	}

	delete[] Array02, Array03;
	// 정적 배열
	int Array04[] = { 0, 2, 3, 4 };

	// 배열의 크기 계산
	int size02 = sizeof(Array04) / sizeof(Array04[0]);//4개 크기를 1개 크기로 나누기

	cout << "Array04 size: " << size02 << endl;

	string Array[] = { "Hello", "World" };
	cout << "String Array contains :" << Array[0] << " & " << Array[1] << endl;

	return 0;
}

결과

요약 비교

       
array (기본 배열 및 std::array) vector list
크기 조정 고정 크기 가변 크기 가변 크기
메모리 할당 방식 연속 메모리 연속 메모리 비연속 메모리
임의 접근 빠름 (arr[i]) 빠름 (vec[i]) 느림 (iterator 필요)
삽입/삭제 성능 중간에 삽입/삭제 비효율적 끝에서만 빠름 중간 삽입/삭제 효율적
사용 예시 고정된 데이터 크기가 변하는 배열 빈번한 삽입/삭제가 필요할 때
선언 방식 int arr[N]; or std::array<int, N> std::vector<int> std::list<int>

 

 


1. 주요 특징

  • 동적 크기 조정: 벡터는 크기가 자동으로 조정되며, 새로운 요소가 추가될 때 필요한 메모리를 자동으로 할당
  • 연속된 메모리: 배열처럼 연속된 메모리 공간을 사용하여 요소에 빠르게 접근
  • 임의 접근 지원: 인덱스를 사용하여 O(1)의 시간 복잡도로 요소에 접근
  • 삽입 및 삭제: 끝에서의 삽입과 삭제는 O(1)이지만, 중간 또는 앞에서의 삽입과 삭제는 O(n)의 시간이 걸림

2. 벡터 선언 및 초기화

벡터 선언

#include <vector>
#include <iostream>

std::vector<int> vec; // 정수형 벡터

초기화 방법

std::vector<int> vec1;                  // 비어 있는 벡터
std::vector<int> vec2(5);               // 크기가 5인 벡터 (모든 값은 0으로 초기화)
std::vector<int> vec3(5, 10);           // 크기가 5인 벡터 (모든 값은 10으로 초기화)
std::vector<int> vec4 = {1, 2, 3, 4};   // 리스트 초기화
std::vector<int> vec5(vec4);            // vec4를 복사하여 생성

3. 주요 메서드 및 사용법

요소 추가 및 삭제

  • push_back(value): 벡터의 끝에 요소를 추가
  • pop_back(): 벡터의 끝에서 요소를 제거
std::vector<int> vec;
vec.push_back(10); // {10}
vec.push_back(20); // {10, 20}
vec.pop_back();    // {10}

크기 확인

  • size(): 현재 벡터의 크기(요소의 개수)를 반환
  • capacity(): 벡터가 메모리를 재할당하지 않고 저장할 수 있는 최대 요소 수를 반환
  • resize(n): 벡터의 크기를 n으로 변경
std::vector<int> vec = {1, 2, 3};
std::cout << vec.size();     // 출력: 3
vec.resize(5);
std::cout << vec.size();     // 출력: 5

접근

  • operator[]: 인덱스를 사용해 요소에 접근
  • at(index): 인덱스를 기반으로 요소에 접근하지만, 경계 검사(boundary check)를 수행
std::vector<int> vec = {1, 2, 3};
std::cout << vec[0];   // 출력: 1
std::cout << vec.at(1); // 출력: 2

초기화 및 삭제

  • clear(): 벡터의 모든 요소를 삭제
  • assign(n, value): 크기가 n이고 모든 요소가 value인 벡터를 생성
std::vector<int> vec = {1, 2, 3};
vec.clear(); // 모든 요소 삭제
vec.assign(5, 10); // {10, 10, 10, 10, 10}

삽입 및 제거

  • insert(pos, value): 특정 위치(pos)에 요소를 삽입
  • erase(pos): 특정 위치(pos)에 있는 요소를 제거
  • erase(start, end): start부터 end 이전까지의 요소를 제거
std::vector<int> vec = {1, 2, 3};
vec.insert(vec.begin(), 0);  // {0, 1, 2, 3}
vec.erase(vec.begin() + 1);  // {0, 2, 3}

정렬 및 탐색

  • std::sort: 벡터를 정렬합니다. <algorithm> 헤더 필요.
  • std::find: 특정 값을 탐색합니다. <algorithm> 헤더 필요.
#include <algorithm>
std::vector<int> vec = {3, 1, 4, 1};
std::sort(vec.begin(), vec.end()); // {1, 1, 3, 4}
auto it = std::find(vec.begin(), vec.end(), 3);
if (it != vec.end()) {
    std::cout << "3 found at index: " << it - vec.begin();
}

4. 기타 메서드

메서드 설명

empty() 벡터가 비어 있는지 확인 (true/false 반환).
front() 첫 번째 요소 반환.
back() 마지막 요소 반환.
swap() 두 벡터의 내용을 교환.

5. 벡터의 동적 메모리 관리

  • 벡터의 크기가 증가하면 메모리가 자동으로 재할당
  • reserve(n): 벡터의 용량을 최소 n으로 예약하여, 불필요한 재할당을 줄임
std::vector<int> vec;
vec.reserve(100); // 메모리를 미리 예약

6. 장점과 단점

장점

  • 배열보다 유연하며, 크기 변경이 쉬움
  • 표준 라이브러리의 다양한 함수와 함께 사용 가능.

단점

  • 중간 삽입/삭제 시 성능 저하 (O(n)).
  • 메모리 재할당 시 오버헤드 발생.

 

관련글 더보기