#include <iostream>
// 문자열 라이브러리
#include <string>
// 벡터 컨테이너 라이브러리
#include <vector>
// C++ 표준 라이브러리
using namespace std;
int main()
{
// 자료 구조는 C언어 문법이다
// C++ 에서는 STL(Standard Template Library)를 사용한다
// STL의 종류
// vector, list, map, set, deque, queue, stack, pair, tuple
// 벡터 컨테이너는 자동으로 메모리가 할당되는 배열이다
// 자동으로 메모리를 할당해주고 알아서 끝에 들어가 주고 알아서 삭제도 해준다
// Template를 사용하기 때문에 데이터 타입은 어느 타입이던지 가능하다
// 맨 뒤에서 삽입과 삭제가 가능하다
// 하지만 배열 기반이므로 삽입 삭제가 빈번하게 일어난다면 효율적이 아니다
// #include <vector> 를 해야한다
// Unity C# : array List Dictionary HashSet
// Native C++ : array<> vector map set
// Unreal C++ : TArray TMap TSet
// vector컨테이너 생성 방법
// 1. 비어있는 vector1 컨테이너 생성
vector<int> vector1;
// 2. 기본값 0으로 초기화된 5개의 요소를 가지는 vector2 컨테이너를 생성한다
vector<int> vector2(5);
for (int i : vector2)
{
cout << i << " ";
}
cout << endl;
cout << endl;
// 3. 2로 초기화된 5개의 요소를 가지는 vector3 컨테이너 생성
vector<int> vector3(5, 2);
for (int i : vector3)
{
cout << i << " ";
}
cout << endl;
cout << endl;
// 4. vector4 컨테이너는 vector3 컨테이너를 복사해서 생성한다
vector<int> vector4(vector3);
for (int i : vector4)
{
cout << i << " ";
}
cout << endl;
cout << endl;
// vector 컨테이너의 멤버 함수들에 대해 알아보기
// push_back() : vector 컨테이너 맨 뒤에 요소를 추가
vector<int> vector5;
vector5.push_back(1);
vector5.push_back(2);
vector5.push_back(3);
vector5.push_back(4);
vector5.push_back(5);
for (int i : vector5)
{
cout << i << " ";
}
cout << endl;
cout << endl;
// at(index) : 인덱스로 요소를 참조한다
// vector5[index] 보다 속도는 느리지만, 범위를 점검하므로 안전하다
int index1 = vector5.at(1);
cout << "vector5.at(1) : " << index1 << endl;
cout << endl;
cout << endl;
// [index] : 배열의 인덱스처럼 요소를 참조한다
// 범위를 점검하지 않으므로 속도가 vector5.at(1) 보다 빠르다
int index2 = vector5[2];
cout << "vector5[2] : " << index2 << endl;
cout << endl;
cout << endl;
// front() : 첫 번째 요소를 참조
int index3 = vector5.front();
cout << "vector5.front() : " << index3 << endl;
cout << endl;
cout << endl;
// back() : 마지막 요소를 참조한다
int index4 = vector5.back();
cout << "vector5.back() : " << index4 << endl;
cout << endl;
cout << endl;
// clear() : 모든 요소를 제거하는 함수
// 요소만 제거하고 메모리는 남아있다.
// size(길이)만 줄어들고, capacity(용량)은 그대로 있다
vector5.clear();
cout << " vector5.clear() : " << vector5.size() << endl;
cout << " vector5.capacity() : " << vector5.capacity() << endl;
cout << endl;
cout << endl;
// 테스트를 위해 값을 추가
for (int i = 1; i <= 5; i++)
{
vector5.push_back(i);
}
for (int i : vector5)
{
cout << i << " ";
}
cout << endl;
cout << endl;
// push_back(7) : 마지막 요소뒤에 요소 7 을 추가
vector5.push_back(7);
for (int i : vector5)
{
cout << i << " ";
}
cout << endl;
cout << endl;
// pop_back() : 마지막 요소 제거
vector5.pop_back();
for (int i : vector5)
{
cout << i << " ";
}
cout << endl;
cout << endl;
// reserve(n) : n개의 요소를 저장할 위치를 예약한다, 미리 동적 할당을 해 놓는다
vector5.reserve(15);
cout << "vecto5.size() : " << vector5.size() << endl;
cout << "vector5.capacity() : " << vector5.capacity() << endl;
cout << endl;
cout << endl;
// resize(n) : 크기를 n개로 변경
// 만일 더 커졌을 경우 default 값이 0으로 초기화 해 준다
vector5.resize(10);
cout << "vecto5.size() : " << vector5.size() << endl;
cout << "vector5.capacity() : " << vector5.capacity() << endl;
cout << endl;
cout << endl;
// resize(n, m) : 크기를 n개로 변경
// 더 커졌을 경우 m값으로 초기화
vector5.resize(15, 3);
cout << "vecto5.size() : " << vector5.size() << endl;
cout << "vector5.capacity() : " << vector5.capacity() << endl;
for (int i : vector5)
{
cout << i << " ";
}
cout << endl;
cout << endl;
// begin() : 첫번째 반복자를 반환한다. 반복자(Iterator)와 함께 사용
// 프로그래밍 언어에서 숫자는 0부터 시작
// 배열에서도 0번째 인덱스부터 시작
// 반복자는 인덱스가 아니다 첫번째 부터 시작
vector5.begin();
cout << endl;
cout << endl;
// end() : 마지막 반복자의 다음 반복자를 반환한다 반복자(Iterator)와 함께 사용
vector5.end();
cout << endl;
cout << endl;
// rbegin() : reverse begin
// 거꾸로 해서 첫 번째 반복자를 반환한다 반복자와 함께 사용
vector5.rbegin();
cout << endl;
cout << endl;
// rend() : reverse end
// 거꾸로 해서 마지막 반복자의 다음 반복자를 반환한다 반복자와 함께 사용
vector5.rend();
cout << endl;
cout << endl;
// size는 데이터가 채워진 요소의 개수이고, capacity는 할당된 메모리 공간이다
vector<string> names;
names.push_back("Tom");
names.push_back("Jane");
names.push_back("John");
names.push_back("Smith");
names.push_back("Emma");
names.push_back("James");
names.push_back("Olive");
names.push_back("Harry");
names.push_back("Lucas");
names.push_back("Owen");
for (string name : names)
{
cout << name << " ";
}
cout << endl;
cout << endl;
// 이런 식으로 메모리 할당을 하는 이유는 push_back이 일어날 때마다 동적할당을 하면
// 비효율적이므로 미리 정해둔 만큼 동적 할당을 하는 것이다
cout << "size : " << names.size() << endl;
cout << "capacity : " << names.capacity() << endl;
cout << endl;
cout << endl;
// vector컨테이너의 size, capacity에 대한 테스트
vector<int> vector6;
for (int i = 0; i < 100; i++)
{
vector6.push_back(i + 1);
cout << vector6[i] << ", size: " << vector6.size() << ", capacity : " << vector6.capacity() << endl;
}
cout << endl;
cout << endl;
}