IMyoungho 2020. 3. 31. 22:57

이번에 풀어볼 문제는 이전에 풀었던 암호문 1228에 하나의 조건만 추가된 문제이다.

이전에는 삽입만 존재했다면 이번에는 삭제가 생겼다. 생각보다 어렵진 않았고

문제를 풀면서 느낀점은 이러한 STL을 이용할 때 iterator를 잘 다뤄야 한다는 것을 느꼈다.

#include <iostream>
#include <list>

using namespace std;

int main()
{
    for(int k=1; k<=10; k++){   // 10개의 테스트 케이스
        int n;                  // 암호문의 길이
        cin >> n;               // 입력
        list <int> ans;         // 암호문을 입력할 리스트
        for(int i=0; i<n; i++){
            int tmp;            // 입력받은 값 임시저장
            cin >> tmp;
            ans.push_back(tmp); // 입력받은 값 리스트에 저장
        }
        int m;                  // 명령어 갯수
        cin >> m;               // 입력
        list <int> ans2;        // 명령어 저장 리스트
        for(int i=0; i<m; i++){
            list <int> ::iterator it=ans.begin(); // 암호문 첫 원소
            char check;    // 명령어 형태를 받음 'I' 인지 'D'인지
            cin >> check;  // 입력
            int x, y;      // 위치와 갯수
            cin >> x >> y; // 입력
            for(int j=0; j<x; j++)
                it++;      // iterator를 위치만큼 옮김
            if(check == 'I'){  // 'I'일 때
                for(int z = 0; z<y; z++){
                    int b;     // 명령어 
                    cin >> b;  // 입력
                    ans2.push_back(b); // 명령어 리스트에 저장
                }
                ans.splice(it,ans2); // 암호문에 해당 위치에 명령어 삽입
            }
            else if(check=='D'){     // 'D'일 때
                for(int z=0; z<y; z++)
                    it=ans.erase(it); // 해당 위치의 암호문 삭제
                    it=ans.begin();   // 양방향 반복자이므로 iterator 지정
                    //이거없이 그냥 it=ans.erase(it++)해도됨
            }
        }
        cout << endl;                // 암호문 리스트 값 10개 출력
        cout << "#" << k <<" ";
        for(int i=0; i<10; i++){
            cout << ans.front() << " "; 
            ans.pop_front();         // 출력한 암호문 제거
        }
        cout <<endl;
    }
    return 0;
}

# 이 문제에서 유의할 사항은 iterartor 중 erase를 사용할 때 잘못이용하면 원소삭제 시 에러가 발생할 수 있다.

iterator는 반복자를 의미하며 컨테이너에 있는 원소를 참조할 때 사용한다. 포인터와 비슷한 녀석이라고 생각하자

 

-> 그 이유는 바로 iterartor의 동작에 있다. 원소삭제 시 iterator의 반응은 크게 2가지이다.

-> RandomAccess Iterator와 Bidirectional Iterator이다.

RandomAccess의 경우 : 원소 삭제 시 자동으로 비어있는 Iterator를 채워주게됨

Bidirectional Iterator의 경우 : 원소 삭제시 iterator가 길을 잃어버림 -> 에러 발생 -> 그러므로 우리는 iterator의 길을 찾아줘야함

 

 

참고 : https://mayple.tistory.com/entry/CSTL2%EC%9E%A5-%EB%B0%98%EB%B3%B5%EC%9E%90iterator

반응형