본문 바로가기

코딩공부

240725 코딩테스트 난관(StringIndexOutOfBoundsException)

https://school.programmers.co.kr/learn/courses/30/lessons/17682

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

이 오류를 어떤 코딩테스트 문제를 풀던지 너무 자주 겪어서 정리해야겠다고 생각이 들게 되었음.

index 값을 설정하는 부분에서 지속적인 실수가 있는듯하다.

 

오류 발생 이유

 

약간 스스로의 고질병인것 같은데, for를 통한 반복문을 매우매우 선호하는데, 순회하는 방법이 나오면 거의 무조건 해당 방법을 사용하다보니 index값을 중간에 수정해야할 부분들에서 많은 실수가 나오는 듯.

이번에 수정한 코드는 다음과 같다.

 

import java.util.ArrayList;
import java.util.List;

class Solution {
    public int solution(String dartResult) {
        int i = 0;
        List<Integer> scores = new ArrayList<>();
        char powChar;
        int lastIndex = 0;

        while (i < dartResult.length()) {
            int score = 0;
            if(i + 1 < dartResult.length() && dartResult.charAt(i) == '1' && dartResult.charAt(i+1) == '0') {
                score = 10;
                i += 2;
            } else {
                score = Character.getNumericValue(dartResult.charAt(i));
                i++;
            }

            if(i < dartResult.length()) {
                powChar = dartResult.charAt(i);
                score = powScore(score, powChar);
                i++;
            }

            if(i < dartResult.length() && (dartResult.charAt(i) == '*' || dartResult.charAt(i) == '#')) {
                if(dartResult.charAt(i) == '#') {
                    score *= -1;
                } else if (dartResult.charAt(i) == '*') {
                    if(!scores.isEmpty()) {
                        lastIndex = scores.size() - 1;
                        scores.set(lastIndex, scores.get(lastIndex) * 2);
                    }
                    score *= 2;
                }
                i++;
            }
            scores.add(score);
        }

        return scores.stream().mapToInt(Integer::intValue).sum();
    }

    public static int powScore(int score, char powChar) {
        return switch (powChar) {
            case 'D' -> (int) Math.pow(score, 2);
            case 'T' -> (int) Math.pow(score, 3);
            default -> score;
        };
    }
}

 

 

일정부분 강사님이 참고용으로 올려주신 것을 참고하였고, 그러다보니 평소와 다르게 하단에 메서드를 추가하기도 했다.

일단 중요한 부분은 *와 #을 추가하는 부분에서의 i++ 부분이었다.

아무생각없이 그 아래 scores.add(score) 아래에서 i++ 를 실행했었는데, 이는 그저 배열에 추가하고 i 증가시켜야한다는 생각만 했을 뿐, i++의 정확한 위치에 대한 고민을 하지않은것 때문이다.

해당 i++ 위에 if문이 실행되었을 때만 i값을 증가시켰어야 하는데, 그것을 올바르지 않은 위치에 입력하다보니 지속적으로 오류가 발생했던 것이다. (특수문자 *이나 #이 없는데도 i 값은 무조건 증가)

 

 

결론

 

코드를 작성할 때. 특히 반복문 계열을 작성할 때 index 값들을 유의깊게 생각할 필요가 있다.

습관적으로 index값의 증감을 하기보다는 코드의 흐름을 다시 한번 확인하는 습관을 들이자.

이런 풀고보니 왜 그랬지? 하는 생각이 드는 실수를 줄여나가도록 노력..