import java.io.*;
import java.util.LinkedList;
import java.util.Queue;
class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
LinkedList<Integer> queue = new LinkedList();
for (int i = 1; i <= n; i++) {
queue.add(i);
}
for (int i = 0; i < queue.size(); i++) {
queue.remove(queue.get(0));
int downNumber = queue.get(0);
queue.remove(queue.get(0));
queue.add(downNumber);
if (queue.size() == 0) {
break;
}
}
System.out.println(queue.size()); // 2
*/
queue의 size가 0일 때 반복문을 멈추게 작성하였지만, queue의 size가 2로 출력되는 이상한 현상이 발생했다. 문제의 원인은 동적으로 변하는 queue의 size를 반복 기준으로 잡았기 때문이다. 이러한 경우 size() 대신 n-1을 세웠으면 해결되는 문제였다.
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
LinkedList<Integer> queue = new LinkedList();
for (int i = 1; i <= n; i++) {
queue.add(i);
}
// 1. while문 사용
while (queue.size() > 1) {
queue.remove();
int downNumber = queue.poll();
queue.add(downNumber);
}
/** 2. for문 사용
for (int i = 0; i < n - 1; i++) {
// 마지막 1개가 남을 때까지만 반복하므로 n-1이다.
queue.remove();
int donwNumber = queue.poll();
queue.add(donwNumber);
}
*/
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
bw.write(String.valueOf(queue.peek()));
bw.flush();
bw.close();
}
}
/**
* 동적으로 변하는 queue.size()를 기준으로 for문을 실행하면 안된다!!!!!!
* queue의 size가 0일 때 멈추라고 했음에도 불구하고 반복문 종료 후 size를 출력하면 2가 출력된다.
* 이러한 경우 while문을 사용하면 간편하다.
* 또는 이러한 경우 변수 n을 사용해도 됐을 것이다.
*
*
for (int i = 0; i < queue.size(); i++) {
queue.remove(queue.get(0));
int downNumber = queue.get(0);
queue.remove(queue.get(0));
queue.add(downNumber);
if (queue.size() == 0) {// 요소가 1개 -> linkedlist는 0부터 시작.
break;
}
}
System.out.println(queue.size()); // 2
*/
public class ProblematicSchedule {
public static void main(String[] args) {
Queue<String> schedule = new LinkedList<>();
schedule.offer("Monday: Beethoven's Symphony No.9");
schedule.offer("Wednesday: Mozart's Requiem");
schedule.offer("Friday: Tchaikovsky's Nutcracker");
// 문제가 있는 부분: for 반복문을 사용하여 Queue의 크기가 동적으로 변하는 상황을 처리
for (int i = 0; i < schedule.size(); i++) {
System.out.println("Performing: " + schedule.poll());
// 예상 결과: 모든 스케줄이 출력됨
// 실제 결과: 절반 가량의 스케줄만 출력됨 (반복문 종류 후 size가 0이 아님)
}
// 반복문 종료 후 남은 스케줄 수 확인
System.out.println("Remaining schedules: " + schedule.size());
// 이 부분에서 남은 스케줄의 수를 확인할 수 있음
}
}
문제의 핵심은 schedule.size()가 poll() 메서드 호출로 인해 반복문 동안 동적으로 감소하기 때문에, 반복문이 기대했던 모든 항목을 처리하지 않는다는 것이다.

동적으로 변하는 Queue를 반복할 땐 while문을 사용하는 것이 가장 좋다.