PS 연습

[자료구조] 백준 문제 풀이 - 1406 에디터

생선묵김치찌개 2022. 4. 9. 00:02

 

스택을 이용하는 문제

[내 풀이]

#include <iostream>
#include <list>
#include <string.h>
using namespace std;


int main()
{
	string word;
	cin>>word;
	int n = word.size();
	list <char> li;
	char order;
	char p_insert;
	for(int i=0; i<n; i++)
	{
		li.push_back(word[i]);
	}
	
	list <char>::iterator cersor = li.end();
	int m;
	cin>>m;
	
	for(int i=0; i<m; i++)
	{
		char p_insert;
		cin>>order;
		if(order=='L') // 왼쪽 한칸
		{
			if(cersor!=li.begin())
				cersor--;
			else
				continue;
		}
		else if(order=='D') // 오른쪽 한칸
		{
			if(cersor!=li.end())
				cersor++;
			else
				continue;
		}
			
		else if(order=='B') // 지워 (마지막 요소 지울때 주의!!!!)
		{
			if(cersor!=li.begin())
			{
				cersor = li.erase(--cersor);
			}
	
		}
		else if(order=='P') // 값 추가해
		{
			cin>>p_insert;
			li.insert(cersor,p_insert);
		}
	}
	
	for(cersor=li.begin(); cersor!=li.end(); cersor++)
	{
		cout<<*cersor;
	}
	cout<<endl;
}

[피드백]

  • 굳이 else로 안나누어도 if문의 조건에 성립이 안되면 그냥 넘어간다 !
  • iterator가 맨 앞에 있나 뒤에 있나를 확인할때 .begin() .end()를 사용하자 ( 포인터를 안붙이고도 확인 가능 ) 
    • 반면 .front() .back() 는 값을 반환하기 때문에 포인터 붙여야함
  • 리스트의 맨 마지막 요소를 지울때 주의할점 !!  (iterator을 계속해서 사용하려면 리스트에 iterator가 계속 연결되어 있어야 함)
cersor = li.erase(--cersor); //cersor 값의 왼쪽을 지우라는 예제였음

이런식으로 링크가 끊기지 않게 반드시 반환값을 통해서 이전 iter을 받아두자. 

+ list에 정의되어 있는 erase() 리턴은 무엇인가? erase()로 삭제한 원소의 다음 원소를 가리키는 이터레이터를 리턴해준다. ex) 세번째 원소를 삭제했으면 네번째 원소를 가리키는 이터레이터를 리턴으로 주는 것이다.

 

(참고글) https://tre2man.tistory.com/242

 

C++ list 자료형 사용법

백준 문제를 풀다가 왠지 배열로 풀면 시간초과가 날 것 같고, 벡터로 풀기 애매한 문제가 있었다. 그래서 링크드 리스트를 기반으로 한 STL 컨테이너를 찾다가, 비교적 적절한 방법을 발견했다.

tre2man.tistory.com

 

  • list li (word.begin(),word.end()); string형 문장을 리스트로 초기화 시킬때 이런식으로 사용한다

 

[다른사람의 풀이]

스택을 통해 푸신분 (스택을 2개(좌측,우측) 설정해서 값을 좌우로 보내면서 커서를 구현하였다)

https://kih0902.tistory.com/28

 

<백준 알고리즘> 1406번 에디터

에디터 성공 한국어   시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율 1 초 (언어별 추가 시간 없음) 128 MB 12836 2890 1976 24.991% 문제 한 줄로 된 간단한 에디터를 구현하려고 한다. 이 편집

kih0902.tistory.com