문제: 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 |