2021. 6. 28. 20:02ㆍC++
STL 컨테이너의 목적은
1.템플릿 기반
2.모든 컨테이너에 적용되는 표준 인터페이스
3.메모리 자동 관리
STL 컨테이너에서의 벡터?
벡터는 어떤 자료형도 넣을 수 있는 동적 배열이다. (어떤 자료형? 기본 데이터, 클래스, 포인터)
그 안에 저장된 모든 요소는 연속된 메모리 공간에 위치=배열
요소 수 증가에 따라도 자동으로 메모리 관리
어떤 요소도 임의 접근 가능
제일 마지막에 요소 추가하기
vector의 맨 뒤 요소 추가!
push_back(<data>);
ex)scores.push_back(30);
vector 맨 뒤 요소 제거
pop_back(); //다만 배열에서는 중간을 빼는 경우는 잦아도 맨 뒤부터 빼는 경우는 적다.
용량과 크기의 차이?
capacity(); vecotr에 할당된 공간 수(최대 공간)
size(); vector에 실제 들어있는 요소 수(실제 데이터 수)
vector 용량 늘리기
reserve(<size>);
vector의 용량을 늘린다.
용량이 증가한다면 새로운 저장 공간을 재할당->기존 요소 모두 새 공간으로 복사
연산 자체가 느릴 수 밖에 없는 연산
ex)데이터 500개를 넣을 때, 32개의 데이터를 잡았다가 차서 64개의 데이터를 잡고...반복
다만? 이런 재할당을 막기 위해서 vector를 생성 직후 호출하면???? 바로 500개에 대한 데이터 최적화 가능
=속도 증가
요소에 접근 operator[](size_t n);
지정된 위치(n)의 요소를 참조로 반환
=>scores[i] = 3;같은 경우에도 값일 경우 원본이 변하지 않는데, 참조라서 변한다.
STL 컨테이너에서는 벡터처럼 for문을 이용해서 모든게 처리가 불가능하다..
왜?? 해쉬 맵이나 여러 방식들은 인덱스로 operator[]를 사용 불가능.
=>그래서 STL 컨테이너 순회를 할 때, 반복자를 사용!!(표준 방식)
반복자(iterator) = 사실상 포인터이다.
vector(또는, STL 컨테이너의 어느것들이든)의 요소들을 순회하는데 사용
vector<<type>>::iterator<name>
std::vector<int>::iterator iter = scores.begin(); //시작을 가리키는 반복자 생성
begin(); vector 첫 요소를 가리키는 반복자 반환
end(); vector 마지막 요소 바로 뒤 요소를 가리키는 반복자 반환 //마지막이 string에서 NULL이었듯 똑같은 원리
앞->뒤 순방향 반복자
뒤->앞 역방향 반복자
순방향
begin()-첫요소
end()-마지막 요소 뒤
역방향
rbegin()-마지막 요소
rend()-첫 요소 앞
resize(n) 벡터 크기를 늘린다.
n값만큼 벡터 크기를 늘리는데 데이터를 제외한 나머지를 0으로 채움(비 효율적-업계에서 사용하기엔)
특정 위치에 요소 삽입하기
insert()
ex)
std::vector<int>::iterator it;
it = scores.begin();
it = scores.insert(it,80);
reserve를 빨리 안잡으면 재할당을 해야하는데 재할당할 위치에 데이터가 들어가있다면 복사로 위치를 옮긴 후
재할당 후 전 위치의 데이터 삭제=생각보다 처리가 느리지는 않지만 성능중시하는 C++업계에서는 이것도 느리다.
특정 위치 요소 지우기
erase()
insert와 사용 방식은 동일
insert는 복사와 재할당 둘다 가능성 있지만
eraser는 복사만 (지우니깐) 지운 후 데이터는 앞으로 정렬
요소 대입하기
assign(size_t n,<data>);
ex)anotherScores.assign(7,100); /100, 100, 100, 100, 100, 100, 100
같은 자료형의 두 벡터를 맞바꾼다
swap(vector& other);
ex) scores.swap(anotherScores);
reserve는 할당을 하지만
resize는 넘어가면 맨 뒤쪽의 데이터를 삭제시킨다
resize는 vector의 크기를 변경하기때문!!
vector의 모든 요소 제거
clear()
vector를 싹 지운다.
size는 0으로 되며 용량은 변하지 않는다.
값을 저장하는 사본을 만드는 것 보다는 주소를 저장해주는 포인터 벡터를 통해 관리 하는 것 이 좋다
=>벡터에는 주소값들이 있고 그 주소값들은 힙에 있는 데이터를 가리킨다.
=>이 방식은 데이터가 많은 경우 reserve로 인한 재할당을 최대한 줄일 수 있고 효율적인 방식이다.
단! iterator를 돌리면서 하나씩 delete를 사용하는 것을 중요하게 생각해야한다.
->지운 뒤에 포인터를 계속 사용하면 안됨(많은 사람이 실수하는 부분)
벡터 장점:
1.순서 상관 없이 요소에 임의적 접근 가능
2.제일 마지막 위치에 요소를 빠르게 삽입 및 삭제(메모리 재할당 없다는 가정)
벡터 단점:
1.중간에 요소 삽입 및 삭제는 느리다.(다만, 삭제의 경우 순서가 상관없을 시 최적화가 가능해서 느리지않음)
2.재할당 및 요소 복사에 드는 비용이 있다.(최대한 reserve사용)