사진은 파리에서 매일 먹은 아침 - 내가 제일 좋아했던 시간! 아침에 빵이랑 커피 한잔 하면서 민박집 다른 분들이랑 오늘 어디 갈지, 어디가 좋은지 얘기하던 시간이 너무 평화롭고 행복했다. 다들 잘 지내고 계시죠?! 전 걱정하던 영국도 잘 다녀왔고 열심히 잘 지내고 있습니다~
오늘 진짜 진짜 힘들었다... 어제도 힘들었지만 오늘은 왠지 더 힘들었다... 어제는 그냥 꽉막혀서 안풀렸는데 오늘은 방법 설계할 때까지만 해도 이렇게까지 헤맬 줄 몰랐고 처음 짠 코드에서 예외가 끝도없어서 진짜 4시간동안 한 문제 디버깅만 함.. 마지막에 눈물흘리면서 런하니까 답 나오더라
자바의 큐는 왜 순회가 안되게 만들어놓은걸까? C++ 로 돌아가고 싶다;;;
결국 풀고 페어분께 코드 공유까지 한건 뿌듯하긴 한데 할거 많은 날에 이러면 안돼ㅜㅜㅜ
자료구조란?
여러 데이터의 묶음을 저장하고 사용 방법을 정의한 것
LIFO (Last In First Out)
push(), pop()
Stack 클래스로 선언, 객체 생성 해주면 됨!!
주요 메서드
-push()
: 스택에 새 데이터 추가
-pop()
: 마지막 추가된 원소 삭제하고 리턴
-size()
: 스택 데이터 개수 리턴
-peek()
: 마지막 추가된 데이터 리턴
-show()
: 스택의 모든 데이터 String타입으로 변환해서 리턴
-clear()
: 스택 비우기
➕ 웹사이트 "뒤로 가기" "앞으로 가기" 가 스택의 개념!
FIFO (First In First Out)
add(), poll()
Queue 클래스로 선언, 객체 생성은 new LinkedList()로 해줘야됨!!
주요 메서드
-add()
: 큐에 새 데이터 추가
-poll()
: 마지막 추가된 원소 삭제하고 리턴
-size()
: 큐 데이터 개수 리턴
-peek()
: 마지막 추가된 데이터 리턴
-show()
: 큐의 모든 데이터 String타입으로 변환해서 리턴
-clear()
: 큐 비우기
⚠️ 큐는 순회하기가 어려움 ‼️
=> 순회 방법이 일일이 poll() 해주고 할때마다 temp 큐에 옮겨담은 다음에 temp 다시 add해서 restore 해주기
➕ 코테에서는 스택보다 큐가 더 많이 쓰임! 그리고 더 어려움;;
~ 내 풀이 ~
import java.util.*;
//다항식 더하기
class Solution {
public static int sum(Queue<Integer> queue) { //가장 최근에 들어온 원소 빼고 큐의 합 구하는 함수
int sum = 0;
int first = queue.peek();
int size = queue.size();
Queue<Integer> temp = new LinkedList<Integer>();
for (int i = 0; i < size; i++) {
int n = queue.poll();
sum += n;
temp.add(n);
}
while (!temp.isEmpty()) { // restore the queue
queue.add(temp.remove());
}
return sum - first;
}
public static boolean isEmpty2(Queue<Integer> queue) { //큐의 모든 원소가 0인지 반환
int size = queue.size();
boolean token = true;
Queue<Integer> temp = new LinkedList<Integer>();
for (int i = 0; i < size; i++) {
int n = queue.poll();
temp.add(n);
if (n != 0) token = false;
}
while (!temp.isEmpty()) { // restore the queue
queue.add(temp.remove());
}
return token;
}
public static int queuePrinter(int bufferSize, int capacities, int[] documents) {
// TODO:
//Initialization
int time = 0; //시간 흐름
Queue<Integer> documentQueue = new LinkedList<>(); //작업해야되는 문서 목록 다 큐로 바꿈
for (int i : documents) {
documentQueue.add(i);
}
Queue<Integer> queue = new LinkedList<>(); //프린터 속 작업 공간 다 큐로 바꿈
for (int i = 0; i < bufferSize; i++) {
queue.add(0);
}
//Process
while (!(documentQueue.isEmpty() && isEmpty2(queue))) {
time++;
if(documentQueue.isEmpty()){ //작업할거 프린터엔 다 들어갔는데 작업 안끝났으면 시간만 흐름(큐 한칸씩 밀기)
queue.add(0);
queue.poll();
}else{
int temp = documentQueue.peek();
if ((sum(queue) + temp) > capacities) { //capacity 초과
//용량초과!
queue.add(0);
queue.poll();
} else { //작업공간에 하나 투입!
queue.add(temp);
documentQueue.poll();
queue.poll();
}
}
}
return time;
}
public static void main(String[] args) {
int bufferSize = 2;
int capacities = 10;
int[] documents = new int[]{7, 4, 5, 6};
// int bufferSize = 90;
// int capacities = 15;
// int[] documents = new int[]{1, 2, 15};
int output = queuePrinter(bufferSize, capacities, documents);
System.out.println(output); // 8
}
}
✔️ Stream, 람다식 활용해서 queue 순회하기!
->
queue.stream().reduce(0, Integer::sum)
굳이 복잡한 함수 따로 만들지 않아도 됐음.
✔️ documents 배열 그대로 써서 Arrays 메서드 활용하기
->
documents = Arrays.copyOfRange(documents, 1, documents.length);
배운건~ 써먹자~^^
✔️ 나머지 구조는 다 똑같은 듯!
레퍼런스 코드는 case처리가 더 자세하게 되어있는데 나는 case 3가지로만 나눠서 썼다. 복잡하게 생각을 못해서 이정도는 그냥 편한대로 해도 되지않을까 싶기도