백준 머신 코드

KIMYEONGJUN·2025년 12월 9일
post-thumbnail

문제

내가 생각했을때 문제에서 원하는부분

예전 프로세서용 머신 코드 프로그램이 주어진다.
프로그램은 최대 200글자로 이루어져 있다.
프로그램은 항상 명령으로 시작한다. (첫 글자가 대문자)
한 명령이 머신 코드에서 여러 번 나오는 경우에, 항상 같은 개수의 파라미터를 갖는다.

삽입해야하는 NOP 개수의 최솟값을 출력한다.

내가 이 문제를 보고 생각해본 부분

BufferedReader를 사용하여 콘솔 입력을 효율적으로 읽는다.
입력으로 들어오는 머신 코드를 machineCode라는 문자열 변수에 저장한다.
nopCount는 최종적으로 출력할, 삽입해야 할 NOP 명령의 총 개수를 저장하는 변수이다. 
0으로 초기화한다.
currentAddress는 현재 처리 중인 명령이나 파라미터가 메모리에서 차지하는 상대적인 시작 주소를 나타낸다. 
메모리의 첫 바이트가 주소 0이므로, 0으로 초기화한다. 
이 변수는 명령이나 파라미터 1바이트당 1씩 증가한다.
for 루프를 사용하여 machineCode 문자열의 각 문자를 처음부터 끝까지 순회한다.
char c = machineCode.charAt(i); 현재 위치의 문자를 가져온다.
루프의 마지막에 currentAddress++;가 있는데, 이는 현재 문자가 명령이든 파라미터든 상관없이 모두 1바이트를 차지하기 때문에 주소를 1 증가시키는 역할을 한다.
if(Character.isUpperCase(c)) 현재 문자가 대문자인지 확인합니다. 대문자일 경우 새로운 명령의 시작이다.
if(currentAddress % 4 != 0) 명령이 시작하는 현재 currentAddress가 4의 배수인지 확인한다. 
만약 4의 배수가 아니라면 NOP를 추가해야 한다.
int neededNops = (4 - (currentAddress % 4)) % 4;
currentAddress % 4는 현재 주소를 4로 나누었을 때의 나머지이다. 
이 나머지가 0이 아니면 4의 배수가 아닌 주소이다.
4 - (currentAddress % 4)는 현재 주소에서 가장 가까운 다음 4의 배수 주소까지 필요한 바이트 수이다. 
예를 들어, currentAddress가 5일 때 나머지는 1이고, 4 - 1 = 3이다.
여기에 % 4를 한 번 더 해주는 이유는, 만약 currentAddress % 4 결과가 0이라면 4 - 0 = 4가 되는데, NOP는 0개만 필요한 경우에도 4개로 계산되는 것을 방지하기 위함이다. 
즉, (4 - 0) % 4는 0이 된다.
결과적으로 neededNops에는 다음 명령 시작 주소를 4의 배수로 맞추기 위해 필요한 NOP 개수가 정확히 저장된다.
nopCount += neededNops; 계산된 neededNops를 총 NOP 개수에 더해준다.
currentAddress += neededNops; NOP가 삽입된 만큼 메모리 주소가 증가하므로, currentAddress도 그만큼 값을 증가시킨다. (이 경우 NOP가 추가되면 주소값이 늘어나므로)
이렇게 해야 다음 명령의 시작 위치를 정확하게 계산할 수 있다.
System.out.println(nopCount);
모든 머신 코드를 순회한 후, 최종적으로 계산된 nopCount를 출력한다.
br.close();
사용한 BufferedReader를 닫아준다.

코드로 구현

package baekjoon.baekjoon_31;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

// 백준 2929번 문제
public class Main1231 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String machineCode = br.readLine();
        int nopCount = 0; // 삽입할 NOP 명령의 총 개수
        int currentAddress = 0; // 현재 바이트 주소

        for (int i = 0; i < machineCode.length(); i++) {
            char c = machineCode.charAt(i);

            // 대문자는 명령의 시작입니다.
            if (Character.isUpperCase(c)) {
                // 현재 명령이 시작하는 위치(currentAddress)가 4의 배수가 아니라면 NOP를 삽입해야 합니다.
                // 4의 배수로 맞추기 위해 필요한 NOP 개수를 계산합니다.
                if (currentAddress % 4 != 0) {
                    // (4 - (현재 주소 % 4)) % 4를 통해 다음 4의 배수까지 필요한 NOP 개수를 정확히 구할 수 있습니다.
                    // 예를 들어, currentAddress가 5라면, 5%4 = 1. (4-1)%4 = 3개의 NOP가 필요합니다.
                    // currentAddress가 4라면, 4%4 = 0. (4-0)%4 = 0개의 NOP가 필요합니다.
                    int neededNops = (4 - (currentAddress % 4)) % 4;
                    nopCount += neededNops;
                    currentAddress += neededNops; // NOP가 추가된 만큼 주소도 증가합니다.
                }
            }
            // 명령이든 파라미터든 모든 문자는 1바이트를 차지하므로, currentAddress를 1 증가시킵니다.
            currentAddress++;
        }

        System.out.println(nopCount);
        br.close();
    }
}

마무리

코드와 설명이 부족할수 있습니다. 코드를 보시고 문제가 있거나 코드 개선이 필요한 부분이 있다면 댓글로 말해주시면 감사한 마음으로 참고해 코드를 수정 하겠습니다.

profile
Junior backend developer

0개의 댓글