article thumbnail image
Published 2022. 9. 28. 00:59

문제: https://www.acmicpc.net/problem/1406

 

 

 

 

#include <iostream>
#include <list>
#include <string>
using namespace std;
list<char> l;
list<char>::iterator t;
string s;
int n;
char cmd;

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);

  cin >> s;
  for (char c : s) l.push_back(c);
  t = l.end();
  cin >> n;
  cin.ignore();

  for (int i = 0; i < n; i++) {
    cin >> cmd;
    switch (cmd) {
      case 'L':
        if (t != l.begin()) t--;
        break;
      case 'D':
        if (t != l.end()) t++;
        break;
      case 'B':
        if (t == l.begin()) continue;
        if (t == l.end()) {
          l.erase(--t);
          t = l.end();
        } else
          t = l.erase(--t);
        break;
      case 'P':
        cin >> cmd;
        l.insert(t, cmd);
    }
  }
  for (auto i : l) cout << i;
}

임의의 자리에 대한 삽입/삭제의 효율적인 연산을 위해 연결리스트를 사용해서 풀었다.

주어진 문자열은 s변수에 담아 한 글자씩 연결리스트 l에 push 한다.

에디터의 커서는 처음엔 맨 뒤에 있으므로 변수 t에 연결리스트의 end iterator를 담는다.

이제 명령어를 입력받고, 각 명령어에 대한 처리를 해야한다.

나는 cmd 변수에 명령어를 담아서 switch문으로 처리했다.

'L'인 경우 t가 l.begin()이 아니라는 조건하에 t--를 한다.

마찬가지로 'D'인 경우 t가 l.end()가 아니라는 조건하에 t++를 한다.

'B'는 커서 앞 문자에 대한 삭제 명령이기 때문에 t가 l.begin()이라면 해당 케이스를 무시하고 넘어가고, 아니라면 l.erase 호출해서 문자를 삭제한다.

이때 t가 아니라 --t를 인자로 전달하는 이유는 커서 앞의 문자를 지워야 하기 때문이다.

erase 메소드는 요소를 삭제한 후 자동으로 iterator가 뒤의 요소를 가르키는 특징이 있다.

때문에 t가 l.end()였다면 l.erase() 호출후에 t = l.end()로 재할당해야 한다.

마지막으로 'P'인 경우 새로 삽입할 문자를 입력받고 insert로 추가하면 된다.

 

 

 

 

 

 

'알고리즘' 카테고리의 다른 글

[BOJ] 1158: 요세푸스 문제  (0) 2022.09.28
[BOJ] 5397: 키로거  (0) 2022.09.28
[BOJ] 10808: 알파벳 개수  (0) 2022.09.23
[BOJ] 3273: 두 수의 합  (0) 2022.09.22
[BOJ] 1475: 방 번호  (0) 2022.09.22
복사했습니다!