본문 바로가기
🥇Problem Solving (psS2mj)/Programmers

[프로그래머스] 프린터 (Java)

by psS2mj 2020. 5. 20.
반응형

코딩테스트 연습 中 스택/큐

문제 링크 / level: 2

https://programmers.co.kr/learn/courses/30/lessons/42587

 

코딩테스트 연습 - 프린터

일반적인 프린터는 인쇄 요청이 들어온 순서대로 인쇄합니다. 그렇기 때문에 중요한 문서가 나중에 인쇄될 수 있습니다. 이런 문제를 보완하기 위해 중요도가 높은 문서를 먼저 인쇄하는 프린��

programmers.co.kr

 

 

내가 생각한 풀이

프로그래머스의 특징은 메소드의 파라미터와 리턴 타입, 변수를 정해준다는 것인데 맨 처음 프로그래머스 문제를 풀 때는 이게 매우 불편했지만 그래도 지금은 몇 문제 풀어봤다고 조금씩 적응해가는 느낌이다.


우선은 스택/큐 라고 적혀있으니 둘 중 하나는 써야겠다 싶었고, 문제를 읽어보니 단번에 큐를 사용해야겠다는 생각이 들었다.

구현하는 과정에서 처음에는 Queue를 사용하다가 배열의 다른 원소들과 비교할 때 get 메소드를 사용하는게 편해서 그냥 아예 LinkedList로 바꾸기는 했지만.

 

아무튼 이 문제에서 파라미터로 주어지는 값은 중요도가 저장되어 있는 일차원 배열(priorities)이고, 이를 토대로 지금 주어진 위치(location)에 있는 작업이 몇 번째로 출력되는지 찾아내면 된다.

문제는 다소 심플한 느낌인데 구현할 때 어떻게 하면 좋을지 살짝 고민을 했다. 왜냐하면 중요도를 검사하기 위해 매번 배열을 쭉 돌아야하고, 큐의 특성인 FIFO도 이용해야하며, 또다른 파라미터 값인 location을 가지고 다니면서 이번에 출력된 녀석이 내가 찾는 그 녀석이 맞는지 확인도 해줘야하기 때문이었다.

 

일해라 머리야!!!

나의 생각:

1. 파라미터로 주어진 일차원 배열의 모든 원소의 값과 그때의 인덱스를 int[] 형태로 리스트에 저장해준다. 그러면 {2,0} {1,1} 이런 형태로 저장이 되겠지. 중요도는 물론 인덱스의 값도 가지고 다닐 수 있으니까 내가 원하는 녀석의 출력 순서를 구할 수 있을 것이다.

2. 일단, 리스트에서 가장 앞에 있는 원소를 빼낸다. 그리고 그때의 리스트 길이만큼 반복문을 돌면서 다른 녀석들과 중요도의 크기를 비교한다. 이때 현재 리스트를 망치면 안되니까 get 메소드를 이용해서 값을 보기만 하자구! (tmp[0]에는 중요도가 저장되고, tmp[1]에는 인덱스가 저장될 것이다.)

3. 2번 로직을 수행하고 있는데 만약 나보다 중요도가 큰 녀석이 하나라도 있다면? 꺼냈던 원소를 맨 뒤에 넣어주고, cnt 변수 값을 1 증가시키고, break한다. 어차피 이미 뒤로 갔으니까 추가로 비교하는 과정은 불필요하겠지.

4. 한편, 만약 나보다 중요도가 큰 녀석이 하나도 없다면 (cnt==0일 때) 내 자신을 출력하면 된다. 문제에서 요구하는 것은 '몇 번째로 출력되는가?'이므로 answer를 1 증가시킨다. 그리고나서 처음에 파라미터 값으로 주어졌던 location과 현재 내가 출력하려고 하는 원소의 인덱스 값이 같다면 while문을 벗어난다. (이게 몇 번이나 반복될지 모르니까 while문을 사용했다.)

 


 

이렇게 생각해보니 간단한 듯 하면서도 뭔가 복잡한 느낌의 문제다.🤨

그래도 로직이 맞는 것 같아 곧바로 구현에 돌입했는데, 앞에서도 잠깐 언급했듯이 처음에는 get 메소드 생각을 못하고 Queue로 짰다가 중요도 비교 과정에서 후퇴하고 LinkedList로 바꿨다.

// 핵심 코드
while(true) {
	int[] curr = list.poll();
	int value = curr[0];
	int loc = curr[1];
	int len = list.size();
	cnt = 0;
	for (int i = 0; i < len; i++) {
		// 인쇄 대기목록의 가장 앞에 있는 문서(J)를 대기목록에서 꺼냅니다.
		int[] tmp = list.get(i);
		// 나머지 인쇄 대기목록에서 J보다 중요도가 높은 문서가 한 개라도 존재하면 J를 대기목록의 가장 마지막에 넣습니다.
		if(tmp[0]>value) {
			list.add(new int[] {value, loc});
			cnt++;
			break;
		}
	}
	// 그렇지 않으면 J를 인쇄합니다.
	if(cnt==0) {
		answer++;
		if(loc==location) {break;}
	}
}

주석의 경우 프로그래머스 문제에 있는 것을 그냥 복붙해서 썼다.

 

그리고 가볍게 통과!!

다행히 한 번에 잘 통과했다.

 

사실 한 번에는 아니고 import한 내용을 복붙 안해줘서 심볼을 찾을 수 없다나 뭐라나 하는 에러가 떴었긴 한데, 아무튼 잘 해결했고 로직은 잘 짰으니까^_^ 만족, 만족, 대만족! 좀 늘긴 늘었나보다 싶은 소소한 기쁨을 느낄 수 있었다.😊👍

 

 

 

💌 전체 코드 보기:

https://github.com/psS2mj/Problem_Solving_Programmers_by_JAVA/blob/master/%EC%BD%94%EB%94%A9%20%ED%85%8C%EC%8A%A4%ED%8A%B8/level%202/Solution_%ED%94%84%EB%A6%B0%ED%84%B0.java

 

psS2mj/Problem_Solving_Programmers_by_JAVA

Programmers (https://programmers.co.kr/) by JAVA. Contribute to psS2mj/Problem_Solving_Programmers_by_JAVA development by creating an account on GitHub.

github.com

반응형

댓글