inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

교안 108p insert, erase

해결된 질문

130

Clain

작성한 질문수 26

0

안녕하세요 🙂 큰돌님

교안 108p에 있는 예제코드를 제가 insert와 erase를 이해하기 위해서 아래와 같이 변경하였는데요.

#include <bits/stdc++.h>
using namespace std;
list<int> a;
void print(list<int> a)
{
    for (auto it : a)
        cout << it << " ";
    cout << '\n';
}

int main()
{
    for (int i = 1; i <= 3; i++)
        a.push_back(i); // a = 1 2 3

    for (int i = 1; i <= 3; i++)
        a.push_front(i); // a = 3 2 1 1 2 3

    auto it = a.begin();
    it++;

    a.insert(it, 1000); // 3 1000 2 1 1 2 3
    a.insert(it, 2000); // 3 1000 2000 2 1 1 2 3
    print(a);

    it = a.begin();
    it++;

    cout << "*it : " << *it << '\n';
    a.erase(it);
    print(a);

    cout << "*it : " << *it << '\n';

    a.pop_front();
    a.pop_back();
    print(a);

    cout << a.front() << " : " << a.back() << '\n';
    a.clear();

    return 0;
}

다음과 같이 변경해서 출력하면,

3 1000 2000 2 1 1 2 3

*it : 1000

3 2000 2 1 1 2 3

*it : 2

2000 2 1 1 2

2000 : 2

이렇게 나오는데, insert와 erase 메서드 모두 매개변수로 전달받은 iterator에다가 각각의 기능을 실행한 뒤 그 다음 위치(그 다음 인덱스)를 가리키도록 바꿔주는 걸까요?

제 예상으로는 출력의 두 번째 *it 이 2000으로 나올 것으로 예상했는데, 2가 나와서

a.erase(it);를 했을 때, it이 인덱스 1을 가리켜서 1000을 지우고 난 뒤, 그 다음 인덱스인 2를 가리키게 돼서 2를 가리키게 된 것으로 이해하였는데 맞을까요??

마찬가지로 위의 insert도 인덱스 1 위치에서 삽입을 한 뒤, it은 인덱스 2를 가리키게 되고, 또 insert 해서 마지막엔 it이 인덱스 3을 가리키는 로직으로 이해하였습니다!

 

혹시 이러한 로직이 맞다면, list만 이런 것인지 다른 자료구조의 insert도 이런지 궁금합니다!

감사합니다.

c++ 코딩-테스트

답변 1

0

큰돌

안녕하세요 clain님 ㅎㅎ

 

a.erase(it);를 했을 때, it이 인덱스 1을 가리켜서 1000을 지우고 난 뒤, 그 다음 인덱스인 2를 가리키게 돼서 2를 가리키게 된 것으로 이해하였는데 맞을까요??

마찬가지로 위의 insert도 인덱스 1 위치에서 삽입을 한 뒤, it은 인덱스 2를 가리키게 되고, 또 insert 해서 마지막엔 it이 인덱스 3을 가리키는 로직으로 이해하였습니다!

>> 해당 코드에 주석을 달아 설명해보겠습니다. 🙂

#include <bits/stdc++.h> 
using namespace std; 
list<int> a; 
void print(list<int> a)
{ 
    for (auto it : a)
        cout << it << " ";  
    cout << '\n'; 
}

int main()
{ 
    for (int i = 1; i <= 3; i++)
        a.push_back(i); // a = 1 2 3 
    for (int i = 1; i <= 3; i++)
        a.push_front(i); // a = 3 2 1 1 2 3

    // 리스트의 시작 부분에서 두 번째 위치를 가리키는 반복자를 생성합니다.
    auto it = a.begin();
    it++;

    // 반복자가 가리키는 위치에 1000을 삽입합니다. 리스트의 상태: 3 1000 2 1 1 2 3
    a.insert(it, 1000); 
    // 같은 위치에 2000을 삽입합니다. 리스트의 상태: 3 1000 2000 2 1 1 2 3
    a.insert(it, 2000); 
    print(a);  

    // 리스트의 시작 부분에서 두 번째 위치를 다시 가리키는 반복자를 설정합니다.
    it = a.begin();
    it++;

    cout << "*it : " << *it << '\n'; // 반복자가 가리키는 원소(1000)를 출력합니다.
    a.erase(it); // 반복자가 가리키는 원소(1000)를 삭제합니다.
    print(a); // 리스트의 현재 상태를 출력합니다.

    // 주의: erase 호출 후 it는 무효화되므로, 여기서 *it를 사용하면 정의되지 않은 동작을 초래합니다.
    cout << "*it : " << *it << '\n'; // 이 코드는 UB를 초래합니다.  
    a.pop_front(); // 리스트의 첫 번째 원소를 삭제합니다.
    a.pop_back(); // 리스트의 마지막 원소를 삭제합니다.
    print(a); // 리스트의 현재 상태를 출력합니다.

    // 리스트의 첫 번째와 마지막 원소를 출력합니다.
    cout << a.front() << " : " << a.back() << '\n';
    a.clear(); // 리스트의 모든 원소를 삭제합니다.

    return 0;
}

저의 경우 이 코드를 실행했더니 2가 아니라 1000이 뜹니다.

3 1000 2000 2 1 1 2 3 
*it : 1000
3 2000 2 1 1 2 3 
*it : 1000
2000 2 1 1 2 
2000 : 2

그 이유는 이 코드에서 UB가 발생하는 부분이 있기 때문입니다.

erase 함수를 호출할 때의 it 이후 해당 반복자 it는 더 이상 유효하지 않습니다. 해당 it에 대한 부분을 지웠는데 다시 해당 부분의 값을 출력하게 되면 정의되지 않은 동작(Undefined Behavior)이 발생할 수 있습니다.

혹시 이러한 로직이 맞다면, list만 이런 것인지 다른 자료구조의 insert도 이런지 궁금합니다!

>> 네 insert가 허용되는 자료구조의 경우 보통 이런 꼴을 띄게 됩니다.

vector의 경우

    vector<int> v = {1, 2, 4, 5};
    // 인덱스 2에 3 삽입
    v.insert(v.begin() + 2, 3);

데큐

    deque<int> d = {1, 2, 4, 5};
    d.insert(d.begin() + 2, 3); // 인덱스 2에 3 삽입

 

set

    set<int> s = {1, 2, 4, 5};
    s.insert(3); // 3 삽입

 

map

    map<int, string> m = {{1, "one"}, {2, "two"}, {4, "four"}};
    m.insert({3, "three"}); // 키 3에 "three" 삽입



또 질문 있으시면 언제든지 질문 부탁드립니다.

좋은 수강평과 별점 5점은 제게 큰 힘이 됩니다. :)

감사합니다.

강사 큰돌 올림.

0

Clain

이해되었습니다~!! 자세하게 설명해주셔서 감사합니다 :)ㅎㅎ

코딩살구클럽 입장이 안됩니다

0

13

1

4-F 경우의 수 질문입니다.

0

26

2

코딩살구클럽 가입이 안됩니다.

0

52

2

살구 클럽에 대한 질문있습ㄴ디ㅏ

0

40

1

교안 158페이지 문의드립니다

0

37

2

코딩살구클럽 관련 건의사항

0

98

1

코살에 19942 다이어트 문제에 N의 범위가 빠져있슴니다

0

40

1

진행 방법 질문드립니다!

0

72

2

2-I) 왜 이 문제가 그래프이론 카테고리에 있는지 잘 모르겠습니다.

0

61

2

2주차 개념#12 트리 순회

0

32

2

백준사이트가 종료된다고 합니다.

0

301

2

백준 서비스 종료

9

919

1

sk 하이닉스 코테 대비

0

378

2

3-G 최댓값 질문

0

52

1

모듈러 연산 값이 10이 아닌 경우도 있지 않나요?

0

84

2

3-I 코드 질문드립니다.

0

63

2

3-N 질문 있습니다.

0

68

2

학습방법

0

104

2

4-H 질문 있습니다 (코드 리뷰)

0

67

2

코딩테스트 어디까지 준비해야 하는지 질문이 있습니다.

0

178

2

2-O 반례가 무엇일지 어떤 부분이 틀렸는지 잘 모르겠습니다.

0

70

2

2주차 개념 #4-2. 인접행렬 질문있습니다.

0

65

2

1-A 문제풀이 후 궁금한 점이 생겨서 질문드립니다.

0

52

2

조합 재귀 풀이 확인 해주시면 감사하겠습니다.

0

70

2