Problem Solving/백준

[백준 BOJ] 5397_키로거

돌돌김 2019. 12. 18. 01:59

https://www.acmicpc.net/problem/5397

 

5397번: 키로거

문제 창영이는 강산이의 비밀번호를 훔치기 위해서 강산이가 사용하는 컴퓨터에 키로거를 설치했다. 며칠을 기다린 끝에 창영이는 강산이가 비밀번호 창에 입력하는 글자를 얻어냈다. 키로거는 사용자가 키보드를 누른 명령을 모두 기록한다. 따라서, 강산이가 비밀번호를 입력할 때, 화살표나 백스페이스를 입력해도 정확한 비밀번호를 알아낼 수 있다. 강산이가 비밀번호 창에서 입력한 키가 주어졌을 때, 강산이의 비밀번호를 알아내는 프로그램을 작성하시오. 입력 첫째 줄에 테

www.acmicpc.net

처음에 이렇게 풀어서 틀렸었다

#include<iostream>
#include<list>

using namespace std;

int main() {
	list<char>password;
	list<char>ans;
	int n;
	string str;
	cin >> n;
	while (n--) {
		cin >> str;
		list<char>::iterator iter = password.begin(); 
		for (int i = 0; i < str.size(); i++) {
			password.push_back(str[i]);
		} 
		while (!password.empty()) {
			char tmp = password.front();
			password.pop_front();
			if (tmp == '<') { // 왼쪽으로 커서 이동
				if (iter != password.begin()) {
					iter--;					
				}
			}
			else if (tmp == '>') {// 오른쪽으로 커서 이동
				if (iter != password.end()) {
					iter++;
				}

			}
			else if (tmp == '-') {//앞에 문자가 있다면 삭제
				if (iter != password.begin()){
					ans.erase(iter);
				}
			}
			else {
				ans.insert(iter,tmp);
				iter++;
			}
			
		}

		while (!ans.empty())
		{
			cout << ans.front();
			ans.pop_front();
		}
		password.clear();
		ans.clear();
	}
}

 

정답 코드

#include<iostream>
#include<list>
#include<string>

using namespace std;

int main() {
	int n;
	cin >> n;
	while (n--) {
		string str;
		cin >> str;
		list<char>password;	
		list<char>::iterator iter = password.begin();

		for (int i = 0; i < str.length(); i++) {
			if (str[i] == '<') { // 왼쪽으로 커서 이동
				if (iter == password.begin()) {
					continue;
				}
				iter--;
			}
			else if (str[i] == '>') {// 오른쪽으로 커서 이동
				if (iter == password.end()) {
					continue;
				}
				iter++;
			}
			/*
			'<'와  '>'는 제대로 함 

			처음에 풀었을 때의 코드
			
			else if (tmp == '-') {//앞에 문자가 있다면 삭제
				if (iter != password.begin()){
					ans.erase(iter);
				}
			}
			else {
				ans.insert(iter,tmp);
				iter++;
			}
			*/					   			 		  
			else if (str[i] == '-') {// 앞에 문자가 있다면 삭제, iter를 앞으로 왼쪽으로 한 칸 옮겨줌
				if (iter == password.begin()) {
					continue;
				}
				/*이 부분이 문제였었다

				  1. 36번 line과 37번 line의 순서가 바뀌었었음
				  2. iter에 password.erase(iter)을 넣어주지 않았음

				*/
				iter--;
				iter = password.erase(iter); // 왜 이렇게 하는거지?

			}
			else {
				password.insert(iter, str[i]);
			}
		}

		/*출력 주의*/
		list<char>::iterator it;
		for (it = password.begin(); it != password.end(); it++) {
			cout << *it;
		}
		cout << endl;
		password.clear();
	}

}

 

문제 자체는 어렵지 않았는데 list의 iterator를 제대로 활용하지 못해서 계속 오류가 났다.

  • erase
    • iterator의 erase는 삭제한 원소의 다음값을 반환한다. 
    • 때문에 erase를 하면 그의 반환값을 다음번 iterator에 담아줘야 한다.