vector

manmarru·2024년 1월 10일

c++

목록 보기
2/24
#include<vector>

void main(
{
	V = vector<int>;
    V = {1,2,3,4}
}
  • 벡터는 배열 기반이라서 노드 기반인 리스트보다 탐색이 용이하다.
    리스트는 임의 접근같은건 시도도 못한다.
  • 새로운 값을 추가하거나 삭제할 때 최악의 경우 O(n) 만큼 비효율적이다.
  • 원소를 지워도 할당된 메모리 공간은 반환되지 않는다.(캐퍼시티)
  • 연속된 메모리 공간을 가지는 동적배열이며, 할당된 공간이 꽉 차면 연속된 더 큰 공간을 재할당하고, 데이터를 전부 옮긴다.

원소 추가하기

  • vector.insert(원소를 넣을 위치의 이터레이터, 넣을 값)
  • vector.push_back(넣을 값)

원소 지우기

  • vector.erase(지울 원소의 이터레이터)

원소 찾기

  • find(begin, end, 값)
  • begin 부터 end 의 범위 내에서 값이 존재하면 해당 이터레이터를 반환하고, 값이 없다면 end 를 반환한다
vector<int> vecTmp;
vecTmp.push_back(1);
vecTmp.push_back(2);
vecTmp.push_back(3);
auto iter = find(vecTmp.begin(), vecTmp.back(), 2); 
//2가 있는 인덱스의 이터레이터가 반환됨

원소에 접근하기

  • 벡터의 주소는 포인터가 아니라 이터레이터 객체다.
    주소 꺼낼 때 이터레이터에 할당해야된다.
vector<int> vecTmp = {1,2,3};
vector<int>::iterator iter;
iter = vecTmp.begin();
  • v.at(i) : i번째 요소에 접근
  • 대괄호연산 오버로딩돼있음
    (범위를 벗어나면 어떤 일이 생길지 모르지만 범위검사를 하지 않기 때문에 v.at()보다 빠르다.)
  • v.front() : 첫 번째 원소를 반환(참조)
  • v.back() : 맨 뒤의 원소를 반환(참조)
  • v.begin() : 첫 번째 원소의 이터레이터를 반환
  • v.end() : 맨 뒤의 이터레이터를 반환
    참고로 맨 뒤는 비어있다. 마지막 원소를 원하면 --v.end()

swap

  • 원소뿐만 아니라 크기까지도 스왑된다.

반복문 호출할때

  • 레퍼런스&를 사용하면 원소의 값을 복사해서 변수에 대입하는게 아니라 원소 자체를 불러올 수 있고, 값을 수정하면 원본의 값이 수정된다.
for (int& v : V)
{
	v += 1;
}
//이후 V는 {2, 3, 4, 5} 가 된다.

최적화에 대해

  • 크기를 자동으로 할당해주고 자동으로 늘려주지만. 이 과정에서 데이터를 옮기는 데 비용이 든다. 정적인 상황이라면 메모리를 지정해서 미리 할당해주도록 하자. (reserve)

resize VS reserve + emplace_back

int 같은 단순한 데이터면 상관없지만 클래스나 구조체처럼 무거운게 들어가면 속도 차이가 난다.

vector<int> Temp;

Temp.resize(Size);
int Input;
for(int i = 0; i < Size; ++i)
{
	cin >> Input;
	Temp.push_back(Input);
}
Temp.reserve(Size);
for(int i = 0; i < Size; ++i)
{
	Temp.emplace_back();
    cin >> Temp.back();
}
// 불필요한 복사/이동이 없다.
// 벡터 내부에서 바로 객체 생성 + 값 대입만 일어남
// 클래스의 경우라면 set함수롤 호출하거나 맴버변수에 cin 하는 형태가 되겠지?

동적 할당 해제

  • 이터레이터를 할당 해제하면 벡터에 대한 정보가 사라지기 때문에 다음 원소로 접근할 수 없다.
  • erase 함수는 지운 원소의 다음 원소의 이터레이터를 반환해준다. 이걸 받아서 다시 지우면 된다.

class cCat

vector<cCat*> CatTower;
for(int i = 0; i < 5; ++i)
{
	CatTower.push_back(new cCat);
}

//지우기
for (auto iter = CatTower.begin(); iter != CatTower.end();)
{
	delete *iter;
	iter = CatTower.erase(iter);
}

CatTower.clear();

0개의 댓글