[java] 문자열 제어 최적화: if문 vs switch문 vs 배열 매핑

CHOI HONGSEO·2026년 4월 2일

자바(Java)로 알고리즘 문제를 풀거나 실무를 하다 보면, 문자열에 포함된 특정 문자(예: 'w', 'a', 's', 'd')에 따라 변수의 값을 다르게 조작해야 하는 경우가 자주 발생합니다.

가장 먼저 떠오르는 방법은 if-else문이겠지만, 상황에 따라 가독성을 높이거나 실행 속도를 극한으로 끌어올리는 다양한 방법이 있습니다. 오늘은 문자열 제어문을 처리하는 4가지 단계를 소개합니다.


1. 기본 중의 기본: if-else문 활용

가장 직관적이고 기본적인 방법입니다. 문자열의 길이만큼 반복문을 돌면서 하나씩 조건을 검사합니다.

public int solution(int n, String control) {
    int count = control.length();
    for (int i = 0; i < count; i++) {
        if (control.charAt(i) == 'w') {
            n += 1;
        } else if (control.charAt(i) == 's') {
            n -= 1;
        } else if (control.charAt(i) == 'd') {
            n += 10;
        } else if (control.charAt(i) == 'a') {
            n -= 10;
        }
    }
    return n;
}

동작에는 전혀 문제가 없지만, 조건이 많아질수록 코드가 길어지고 else if를 계속 타야 하므로 미세한 성능 저하가 발생할 수 있습니다.


2. 성능과 가독성을 한 번에: 향상된 switch

if-else문보다 미세하지만 더 효율적이고 가독성도 훨씬 좋은 것이 바로 switch문입니다. 특히 Java 14부터 지원하는 화살표(->) 문법을 사용하면 코드가 예술적으로 깔끔해집니다.

public int solution(int n, String control) {
    for (int i = 0; i < control.length(); i++) {
        switch (control.charAt(i)) {
            case 'w' -> n += 1;
            case 's' -> n -= 1;
            case 'd' -> n += 10;
            case 'a' -> n -= 10;
        }
    }
    return n;
}

왜 더 빠를까요?
자바에서 switch문은 컴파일될 때 내부적으로 '해당 위치로 바로 점프'하는 방식(tableswitch 또는 lookupswitch)으로 최적화됩니다. 따라서 위에서부터 아래로 조건을 하나씩 다 검사해야 하는 if-else문보다 조건이 많을수록 더 빠른 성능을 보여줍니다.


3. 실무/코테 추천 스타일: toCharArray() + 향상된 for

인덱스 i를 써서 charAt(i)로 접근하는 대신, 문자열을 문자 배열(char[])로 바꿔서 향상된 for문을 쓰면 코드가 훨씬 읽기 편해집니다.

public int solution(int n, String control) {
    for (char c : control.toCharArray()) {
        switch (c) {
            case 'w' -> n += 1;
            case 's' -> n -= 1;
            case 'd' -> n += 10;
            case 'a' -> n -= 10;
        }
    }
    return n;
}

가장 권장하는 스타일입니다. 코딩 테스트에서 작성 속도도 빠르고, 다른 개발자가 읽기에도 가장 직관적입니다.


4. 극한의 성능 최적화: 배열 매핑 (조건문 없애기)

만약 control 문자열의 길이가 1억 개쯤 되어서 "0.001초라도 실행 속도를 더 줄이고 싶다!"면 어떻게 해야 할까요?
이럴 때는 아예 ifswitch 같은 조건문 자체를 없애버리는 방법을 쓸 수 있습니다. 문자가 내부적으로는 아스키코드(숫자)라는 점을 이용하는 것입니다.

public int solution(int n, String control) {
    // 알파벳 소문자 아스키코드의 최대값(z=122)을 덮을 수 있는 넉넉한 크기의 배열 생성
    int[] move = new int[128]; 
    
    // 각 문자에 해당하는 위치에 변화량을 미리 적어둡니다.
    move['w'] = 1;
    move['s'] = -1;
    move['d'] = 10;
    move['a'] = -10;
    
    // 조건문(분기) 없이 배열 인덱스로 접근해 그냥 값을 더해버립니다!
    for (int i = 0; i < control.length(); i++) {
        n += move[control.charAt(i)];
    }
    return n;
}

이게 왜 압도적으로 빠를까요?
CPU는 코드 실행 중 ifswitch 같은 조건문을 만날 때마다 "다음엔 어느 쪽으로 갈까?" 하고 예측(분기 예측, Branch Prediction)을 하느라 시간을 씁니다. 하지만 이 방식은 그런 고민 없이 배열에서 값을 바로 꺼내 더하기만 하므로 압도적으로 빠른 속도를 자랑합니다. 알고리즘 고수들이 종종 쓰는 테크닉입니다.

profile
곧 성공할 개발자입니다.

0개의 댓글