자바(Java)로 알고리즘 문제를 풀거나 실무를 하다 보면, 문자열에 포함된 특정 문자(예: 'w', 'a', 's', 'd')에 따라 변수의 값을 다르게 조작해야 하는 경우가 자주 발생합니다.
가장 먼저 떠오르는 방법은 if-else문이겠지만, 상황에 따라 가독성을 높이거나 실행 속도를 극한으로 끌어올리는 다양한 방법이 있습니다. 오늘은 문자열 제어문을 처리하는 4가지 단계를 소개합니다.
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를 계속 타야 하므로 미세한 성능 저하가 발생할 수 있습니다.
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문보다 조건이 많을수록 더 빠른 성능을 보여줍니다.
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;
}
가장 권장하는 스타일입니다. 코딩 테스트에서 작성 속도도 빠르고, 다른 개발자가 읽기에도 가장 직관적입니다.
만약 control 문자열의 길이가 1억 개쯤 되어서 "0.001초라도 실행 속도를 더 줄이고 싶다!"면 어떻게 해야 할까요?
이럴 때는 아예 if나 switch 같은 조건문 자체를 없애버리는 방법을 쓸 수 있습니다. 문자가 내부적으로는 아스키코드(숫자)라는 점을 이용하는 것입니다.
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는 코드 실행 중 if나 switch 같은 조건문을 만날 때마다 "다음엔 어느 쪽으로 갈까?" 하고 예측(분기 예측, Branch Prediction)을 하느라 시간을 씁니다. 하지만 이 방식은 그런 고민 없이 배열에서 값을 바로 꺼내 더하기만 하므로 압도적으로 빠른 속도를 자랑합니다. 알고리즘 고수들이 종종 쓰는 테크닉입니다.