[문제 설명]
창영이는 강산이의 비밀번호를 훔치기 위해서 강산이가 사용하는 컴퓨터에 키로거를 설치했다. 며칠을 기다린 끝에 창영이는 강산이가 비밀번호 창에 입력하는 글자를 얻어냈다.
키로거는 사용자가 키보드를 누른 명령을 모두 기록한다. 따라서, 강산이가 비밀번호를 입력할 때, 화살표나 백스페이스를 입력해도 정확한 비밀번호를 알아낼 수 있다.
강산이가 비밀번호 창에서 입력한 키가 주어졌을 때, 강산이의 비밀번호를 알아내는 프로그램을 작성하시오. 강산이는 키보드로 입력한 키는 알파벳 대문자, 소문자, 숫자, 백스페이스, 화살표이다.
입력
첫째 줄에 테스트 케이스의 개수가 주어진다. 각 테스트 케이스는 한줄로 이루어져 있고, 강산이가 입력한 순서대로 길이가 L인 문자열이 주어진다. (1 ≤ L ≤ 1,000,000) 강산이가 백스페이스를 입력했다면, '-'가 주어진다. 이때 커서의 바로 앞에 글자가 존재한다면, 그 글자를 지운다. 화살표의 입력은 '<'와 '>'로 주어진다. 이때는 커서의 위치를 움직일 수 있다면, 왼쪽 또는 오른쪽으로 1만큼 움직인다. 나머지 문자는 비밀번호의 일부이다. 물론, 나중에 백스페이스를 통해서 지울 수는 있다. 만약 커서의 위치가 줄의 마지막이 아니라면, 커서 및 커서 오른쪽에 있는 모든 문자는 오른쪽으로 한 칸 이동한다.
출력
각 테스트 케이스에 대해서, 강산이의 비밀번호를 출력한다. 비밀번호의 길이는 항상 0보다 크다.
예제 입력 1 복사
2
<<BP<A>>Cd-
ThIsIsS3Cr3t
예제 출력 1 복사
BAPC
ThIsIsS3Cr3t
[문제 풀이]
처음에는 배열을 이용해서 문제를 풀려고 생각했는데..
스택 두개를 사용하면 쉽게 풀수있을거같다는 생각이 들어서 한번 풀어봤다.
1번 스택은 입력되는 문자열을 집어넣는 용도로 사용되고, 즉 1번 스택의 top의 다음 위치가 현재 커서의 위치가 된다.
2번 스택은 커서가 앞으로 이동했을때 커서 뒤쪽에 있는 문자들을 저장하는 용도로 사용하면 된다.
1번 스택이 비어있다는것은 현재 커서가 맨 앞에 위치해 있다는것을 의미한다.
2번 스택이 비어있다는 것은 현재 커서가 맨 뒤에 위치해 있다고 생각 할 수 있다.
1번 예제로 예를 들어보면,
1번 스택이 비어있는 상황은 커서가 맨 앞에 위치해 있으므로 '<' 입력이 들어오면 무시하면 된다.
그 이후 'B', 'P'를 차례대로 1번 스택에 넣어준다.
1번 스택에 'B','P'가 있는 상황에서 '<' 입력을 받았으니 2번스택에 'P'를 저장해주고 1번 스택에서 'P'를 빼내어준다.
1번 스택의 top은 'B'이므로 현재 커서는 'B' 뒤에 있다.
이후 입력 'A'에서 1번 스택에 푸쉬해주면 지금까지의 1,2번 스택의 상황은
1: BA
2: P
이 된다.
위의 상황에서 '>' 입력이 들어오는데
1: BAP
2: ""
위와 같이 2번 스택의 top부터 '>'입력이 들어오는 만큼 빼내어 1번스택에 넣어주면 된다.
2번 스택이 비어있을때 '>' 입력이 들어오는것은 의미가 없으므로 무시해주면 된다.
'd' 입력이 들어왔을때 1번 스택의 top 값을 빼내어 주면 된다.
아래는 1번 예제가 1번 2번 스택에 입력되는 순서이다.
1. '<' -> 1 : "" / 2 : "" - 무시
2. '<' -> 1 : "" / 2 : "" - 무시
3. 'B' -> 1 : 'B' / 2 : ""
4. 'P' -> 1 : "BP" / 2 : ""
5. '<' -> 1 : "B" / 2 : "P"
6. 'A' -> 1 : "BA" / 2 : "P"
7. '>' -> 1 : "BAP" / 2 : ""
8. '>' -> 1 : "BAP" / 2 : "" - 무시
9. 'C' -> 1 : "BAPC" / 2 : ""
10. 'd' -> 1 : "BAPCd" / 2 : ""
11. '-' -> 1 : "BAPC" / 2 : ""
한가지 조심해야 할 점은,
위와 같이 풀이를 했을때 커서가 중간에 있는 상황에서 입력이 종료된다면
예를 들어 입력이 "AAA<<"로 들어오게 된다면
1번 스택에 A
2번 스택에 AA가 들어있는 상태로 코드가 종료되게 된다.
2번 스택은 커서를 위해 임시로 뒤에 있는 문자들을 저장하는 변수이므로,
코드의 마지막에 2번 스택이 비워질때까지 1번스택에 넣어주면 정답이 된다.
이해가 안되거나 더 효율적이게 풀 수 있는 부분은 댓글 남겨주시면 답글 달도록 하겠습니다.
파이팅 !
코드가 깨끗하고 명확하게 보일진 모르겠지만, 누군가에게 도움이 될 수도.. 있기에..
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
vector<char> v;
vector<char> back;
int T;
cin >> T;
for(int i =0; i < T; i++)
{
v.clear();
back.clear();
string s;
cin >> s;
int stringSize = s.size();
for(int j = 0; j < stringSize; j++)
{
switch(s[j])
{
case '<':
if(v.empty()) continue;
back.push_back(v.back());
v.pop_back();
break;
case '>':
if(back.empty()) continue;
v.push_back(back.back());
back.pop_back();
break;
case '-':
if(v.empty()) continue;
v.pop_back();
break;
default:
v.push_back(s[j]);
}
}
while(!back.empty())
{
v.push_back(back.back());
back.pop_back();
}
for(const char& iter : v)
{
cout << iter;
}
cout << "\n";
}
}
'Problem Solving > 백준' 카테고리의 다른 글
[백준 11726번] - 2xn 타일링(C++) (0) | 2022.08.10 |
---|---|
[백준 1463번] - 1로 만들기 (0) | 2022.07.30 |
[백준 1697번] - 숨바꼭질 (0) | 2022.07.30 |
[백준 10971번] - 외판원 순회 2 (0) | 2022.07.30 |
[백준 10773번] - 제로 (C++) (0) | 2022.07.20 |