1. 문제
https://www.acmicpc.net/problem/1406
1406번: 에디터
첫째 줄에는 초기에 편집기에 입력되어 있는 문자열이 주어진다. 이 문자열은 길이가 N이고, 영어 소문자로만 이루어져 있으며, 길이는 100,000을 넘지 않는다. 둘째 줄에는 입력할 명령어의 개수
www.acmicpc.net
2. 풀이과정
키보드 입력, 삭제, 커서의 동작을 코드로 표현하는 문제
커서의 움직임으로 중간의 데이터를 자주 삽입, 삭제를 하므로 list(양방향 연결리스트) 사용
1. 문자열을 입력받고 구성하는 한 문자씩 양방향 연결리스트에 삽입
2. cursor = li.end(); 로 커서(iterator)의 시작점을 두었다.
li.end()는 현재 연결리스트의 마지막 요소의 다음위치를 가르킵니다.
cursor는 iterator로 요소의 위치를 가르키는 변수명입니다.
3. 입력받는 명령어에 따른 처리를 나눈다.
- L : 커서가 맨 앞이 아닌 경우에만 좌측으로 iterator를 한칸 옮긴다 -> it--;
- D : 커서가 맨 뒤가 아닌 경우에만 우측으로 iterator를 한칸 옮긴다 -> it++;
- B : 커서가 맨 앞이 아닌경우에는 cursor가 가리키는 앞의 문자를 지워야함으로 cursor를 하나 줄여 그 위치의 값을 erarse한다. 그 후 지운 다음 요소의 위치를 cursor로 두어 제자리로 돌린다. 여기서 list의 erase함수로 원소를 지우면 지워진 원소 다음 원소의 iterator가 반환된다. 이 반환 값을 다시 cursor로 하여 커서를 제자리로 돌린다.
- P : 삽입할 문자를 추가로 하나 더 입력받고 li.insert()를 사용해 현재 커서위치 앞에 문자를 삽입한다.
li.insert(cursor, c) cursor의 앞의 위치에 c를 삽입한다. cursor는 변하지 않는다.
4. 처리 이후 list의 요소들을 출력한다.
삽입, 삭제 구현할때 cursor(iterator)의 위치때문에 정신없었는데
핵심은 지우고 삽입해도 커서의 위치는 변하지 않는다는 점인 것 같네요.
로직 예시
3. C++ 정답 코드
#include <iostream>
#include <list>
using namespace std;
int main()
{
ios::sync_with_stdio(0); cin.tie(0);
list <char> li; //양방향 연결리스트 선언
string str;
cin >> str;
for (const auto &c : str) //한 문자씩 연결리스트에 넣기
li.push_back(c);
list<char>::iterator cursor = li.end();
int t;
cin >> t;
while(t--)
{
char input;
cin >> input;
if (input == 'L')
{
if (cursor != li.begin())
cursor--;
}
else if (input == 'D')
{
if (cursor != li.end())
cursor++;
}
else if (input == 'B')
{
if (cursor != li.begin())
{
cursor--;
cursor = li.erase(cursor);
}
}
else if (input == 'P')
{
char insertChar;
cin >> insertChar;
li.insert(cursor, insertChar);
}
}
for (const auto &c : li)
cout << c;
return 0;
}
'🏆 PS(Problem Solving) > Baekjoon' 카테고리의 다른 글
[C++] 백준 6198 옥상 정원 꾸미기 (0) | 2024.05.09 |
---|---|
[C++] 백준 24511 queuestack (0) | 2024.05.08 |
[C++] 백준 4949 균형잡힌 세상 (0) | 2024.03.13 |
[C++] 백준 1427 소트인사이드 (0) | 2024.03.11 |
[C++] 백준 2563 색종이 (0) | 2024.03.09 |