C++프로그래밍/자료구조,알고리즘(추후확장)

vector의 삽입삭제, 인덱스접근

season97 2024. 9. 28. 12:59

※ C / C++을 이미 알고 있으나 개인적인 공부를 위해 포스팅 하는 글이므로

C++에 대한 구체적인 정보를 담고 있지 않습니다.


vector는 한마디로 동적배열

vector의 동작 원리(size / capacity)

중간 삽입/삭제

처음/끝 삽입/삭제

인덱스 접근

 

# vector 

ㆍ 동적 배열이라 함은 동적으로 커지는 배열.... = 배열

 

ㆍ 원소가 하나의 메모리 블록에 연속적으로 저장된다.

 


 

 

# 중간 삽입/삭제

ㆍ 중간에서 삽입하려면 2 3 4 5 데이터는 뒤로 1칸씩 밀어줘야 한다.. 삽입,삭제는 배열의 끝에서만 효율적이다.

 

ㆍ 삭제도 마찬가지로 빈 공간이 있으면 메모리 블록에 연속적인 저장된 형태가 아니게 된다.  따라서 1칸씩 앞으로 밀어준다.

 v.insert(v.begin() + 2, 5);
 cout << v[2] << endl;
 v.erase(v.begin() + 2);
 cout << v[2] << endl;

ㆍ 2번째공간에 5가 들어갔다 나왔다하는게 잘 찍힌다... insert와 erase를 보면 v.begin()+2 이런 방법처럼 가독성이 살짝 떨어지게 되어있는데 의도적으로 비효율적이기 때문에 접근하기 어렵게 해둔 것

 

vector<int>::iterator insertit = v.insert(v.begin() + 2, 5);
vector<int>::iterator eraseit1 = v.erase(v.begin() + 2);
vector<int>::iterator eraseit2 = v.erase(v.begin() + 2, v.begin()+4);

ㆍ 뭐 여러가지로 활용 가능하다. 근데 디버그 테스트를 하려고 돌렸는데 1줄을 실행하니 딱 이렇게 메모리가 빈공간으로 변한다..!

 

※ 캐퍼시티 때문이다! 용량이초과해서 다른곳으로 복사하고 기존 공간이 삭제되는걸 실습으로 발견할 수 있었다

v.reserve(1000);

ㆍ 지금은 그냥 실습할려고 하는거니까 메모리 용량을 넉넉하게 잡아줬다.

ㆍ insert, erase다 잘 작동하며 이터레이터는 삽입한 위치, 삭제한 위치를 반환한다.

 

ㆍ 또한 범위 삭제는 begin() +2 , begin() +4의 위치는 지워지지않으며 그 사이의 값들만 지워주고, 이터레이터는 뒤에 오는 위치를 반환해준다

 

 

★ 비효율적이라 사용하지 않을 것 같지만 종종 사용할 일이 있다...

 

ㆍ 쭉~ 스캔을 하면서 , 3이라는 데이터가 있으면 일괄 삭제 하고싶다... 라는 상황이라던지!

 

※ 할 가능성이 큰 실수들

  for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
  {
      int data = *it;
      if (data == 3)
      {
          v.erase(it);
      }
  }

ㆍ 터진다. 이렇게하면 더 이상 이터레이터가 유효하지 않게된다. 디버깅을 까보자

proxy값이 null로 되었다..

 

ㆍ 이렇게 하면 정상 작동 한다.. 하지만 3번째가 지워졌고 메모리는 한블록씩 앞으로 땡겨졌다.

ㆍ 이 상태에서 for 반복문에서 ++it을 해주면 4번째 데이터는 체크하지 않고 5번째 데이터로 넘어간다. 따라서

for (vector<int>::iterator it = v.begin(); it != v.end();)
{
    int data = *it;
    if (data == 3)
    {
       it =  v.erase(it);
    }
    else
    {
        ++it;
    }
}

ㆍ위 과정들이 vector와 it에 erase를 사용하면 이렇게 코드를 작성해야 하는 이유이다.

더보기

※ 추가하자면 for문에서 clear() 를 했으면 break로 for문 중단시키자


 

 

 

 

# 처음 끝 삽입/삭제

ㆍ 처음에서 삭제하는것은 데이터를 또 한칸씩 뒤로 밀어줘야 한다... 따라서 삽입,삭제는 배열의 끝에서만 효율적이다.

 

 

# 인덱스 접근

 

※ i번째 데이터는 어디 있습니까?? → v[i]

ㆍ 이런게 가능한 이유는 데이터들이 메모리 블록에 옹기종기 연속적으로 이어져있는 특성 덕분에 가능한 것이다 

인덱스 접근은 허용한다.

'C++프로그래밍 > 자료구조,알고리즘(추후확장)' 카테고리의 다른 글

list와 list의 이터레이터  (0) 2024.09.29
vector 직접 구현해보기  (1) 2024.09.28
vector와 iterator  (1) 2024.09.28
vector의 동작 원리(size / capacity)  (0) 2024.09.28
콜백함수  (0) 2024.09.27