[JAVA] 2870-수학숙제 🩶4 : 문자열을 Integer.parseInt()로 형변환하려면 int형이 담을 수 있는 문자열 길이여야 가능하다.

2026. 2. 5. 13:48·Problem Solve

들어가며

https://www.acmicpc.net/problem/2870

문제 이해는 크게 어렵지 않다. 영어 소문자와 숫자로 이루어진 문자열이 N줄에 걸쳐서 주어지는데, 그 문자열 사이에서 숫자를 쏙쏙 골라 오름차순으로 출력하는 문제였다.

본문으로

그래서 음~ 간단한 문자열 활용 문제구나 싶어서 문자열마다 숫자인지, 영어인지 판단해서 숫자만 뽑는 로직을 아래처럼 구현했다. 숫자가 한자리수가 아니라 큰 숫자면 바로 담으면 안되길래 로직이 좀 길어졌다.

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(bf.readLine());
        List<Integer> list = new ArrayList<>();

        for (int i = 0; i < N; i++) {
            String line = bf.readLine();
            boolean isNumber = false;
            boolean isNextNumber = false;
            String number = "";
            
            for (int j = 0; j < line.length() - 1; j++) { // 마지막 전까지 확인
                isNumber = false;
                isNextNumber = false;
                char digit = line.charAt(j); 
                char nextDigit = line.charAt(j + 1); 
                if (!(digit >= 'a' && digit <= 'z')) { // 현재 확인하고 있는 문자가 숫자인지
                    isNumber = true;
                }
                if (!(nextDigit >= 'a' && nextDigit <= 'z')) { // 다음 문자가 숫자인지
                    isNextNumber = true;
                }

                if (isNumber && !isNextNumber) { // 만약 다음문자가 숫자가 아니라면 여기까지 잘라서 리스트에 넣는다.
                    number += digit;
                    list.add(Integer.parseInt(number));
                    number = "";
                }
                if (isNumber && isNextNumber) { // 다음 문자도 숫자라면, 바로 리스트에 넣는 것이 아니라 연장한다.
                    number += String.valueOf(digit);
                }
            }

            if (isNextNumber) { // 인덱스 오류를 피하기 위하여 마지막 문자는 따로 검사한다.
                number += String.valueOf(line.charAt(line.length() - 1));
                list.add(Integer.parseInt(number));
            }
        }

        list.sort(Integer::compareTo);
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

    }
}

나름 길어졌지만, 절차지향적으로 읽다보면 나름 직관적이라고 생각해서 예제 입력 확인만 하고 바로 제출했다. 하지만 런타임 에러가 난다. "실패했습니다"도 아니고 런타임 에러라니..? 경험 부족해서 그런가 런타임 에러가 뜨니까 뭐부터 고쳐야 할지 막막했다. 로직이 틀린건가 싶어서 생각해봤는데, 크게 틀리다고도 생각 들진 않았다.

 

결국 못참고 AI에게 물어봤는데, "만약 입력값으로 99자리의 문자열 숫자가 들어오면 내 로직은 터진다" 라고 했다. 듣자마자.. 아...

int의 범위는 아래와 같다.

-2,147,483,648 ~ 2,147,483,647 (약 10자리)

즉 10자리 밖에 받지 못해서, 이 문제는 정수 비교로 단순하게 정렬되는 문제가 아니였다. int으로 형변환하면 무조건 런타임에 에러난다.

문제에도 아래 사진과 같이 각 줄은 최대 100글자라고 적혀있다... 분명 확인했는데, 아무 이상함도 느끼지 못했다.. 다음번엔 꼭 느끼자!


그래서 다시 정렬하자면! int형으로는 비교하기 어려우니 문자열(사전순) 그대로 비교해야한다! 어떻게 해야할까..? 아래 다시 고친 정답코드를 보자. 주석을 나름 친절하게 써보았다.

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(bf.readLine());
        List<String> list = new ArrayList<>();

        for (int i = 0; i < N; i++) {
            String line = bf.readLine();
            String number = "";
            boolean isStart = false; // 숫자가 시작중인지 아닌지를 판단하는 플래그 변수

            for (int j = 0; j < line.length(); j++) {
                Character ch = line.charAt(j);

                if (Character.isDigit(ch)) { // 숫자일경우
                    isStart = true;
                    if (number.isEmpty() && ch == '0') { // 앞에는 0이 오지 못한다.
                        continue;
                    }
                    number += ch;
                } else { // 숫자 아닐 경우
                    if (isStart) {
                        if (number.isEmpty()) { // 숫자 시작했는데? 비어있다는 것은 0이 들어왔다는 것.
                            list.add("0");
                        } else {
                            list.add(number);
                        }
                        number = "";
                        isStart = false;
                    }
                }
            }
            if (isStart) { // 줄 끝에서 숫자로 끝난 경우
                if (number.isEmpty()) { // 숫자 시작했는데? 비어있다는 것은 0이 들어왔다는 것.
                    list.add("0");
                } else {
                    list.add(number);
                }
            }
        }

        list.sort((o1, o2) -> {
            if (o1.length() != o2.length()) {
                return o1.length() - o2.length();
            } else {
                return o1.compareTo(o2);
            }
        });

        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

    }
}

숫자가 진행중인지 아닌지를 판단하는 플래그 변수 하나만 두는 것으로 바꾸었다.

그리고 정렬 함수를 보면 길이가 다를때는 오름차순으로 정렬하고, 같을때는 사전순으로 비교(compareTo)하는 것으로 바꾸었다. 

그 전에는 숫자인지 문자의 아스키코드 값 비교로 진행했었는데, Character.isDigit()이라는 메서드를 활용해서 숫자 비교를 하는 것이 더욱 더 깔끔한 것 같다.

마무리하며

입력은 어쩔 수 없이 문자열로 받으니, 그 범위와 길이를 잘 확인해서 형변환할 자료구조가 담을 수 있는 지 판단하고 로직 구현에 들어가야겠다. 아예 처음부터 틀려버리니 너무 되돌아간 느낌이 강하다. 코딩테스트 때 이러면 혼자 맞은줄 알고 시간 소모가 심각할 것이다. 

새롭게 배운 Character.isDigit(), 문자열 비교 로직 꼭꼭 머릿속에 기억해두자~

'Problem Solve' 카테고리의 다른 글

[JAVA] 16637 - 괄호 추가하기 💛3: 방향이 있는 그래프(DAG)에서의 완전탐색은 자신있게 구현하자!  (0) 2026.02.17
[JAVA] 3474 - 교수가 된 현우 🩶3 : 시간복잡도가 위험할 땐 모듈러 다음으론 제곱수를 생각하자.  (0) 2026.02.05
[JAVA] 2910-빈도정렬 🩶3: 정렬 로직을 자유자제로 적용하자  (0) 2026.02.04
[JAVA] 1629번-곱셈 🩶1, 4375번-1 🩶3 : 자료형의 범위를 벗어나는 상황에서는 모듈러 연산의 특징을 이용하자. (정수론)  (0) 2026.02.01
[JAVA] 11286번 절댓값 힙 🩶1 : 시간초과...💥 우선순위 큐(Priority Queue)가 뭔데..?  (1) 2026.01.21
'Problem Solve' 카테고리의 다른 글
  • [JAVA] 16637 - 괄호 추가하기 💛3: 방향이 있는 그래프(DAG)에서의 완전탐색은 자신있게 구현하자!
  • [JAVA] 3474 - 교수가 된 현우 🩶3 : 시간복잡도가 위험할 땐 모듈러 다음으론 제곱수를 생각하자.
  • [JAVA] 2910-빈도정렬 🩶3: 정렬 로직을 자유자제로 적용하자
  • [JAVA] 1629번-곱셈 🩶1, 4375번-1 🩶3 : 자료형의 범위를 벗어나는 상황에서는 모듈러 연산의 특징을 이용하자. (정수론)
노을을
노을을
진인사대천명
  • 노을을
    노을의 개발일기장
    노을을
  • 전체
    오늘
    어제
    • All (105) N
      • Java & Kotlin (16)
      • Problem Solve (46)
      • Spring (4)
      • Infra (3) N
      • DB (2)
      • Project (2)
        • SOMA (1)
        • OJik (1)
      • OpenSource (3)
      • Various Dev (23)
        • 우아한테크코스 (9)
        • Git&Github (2)
        • Unity (12)
      • Book (3)
      • Writing (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • github
  • 공지사항

  • 인기 글

  • 태그

    알고리즘
    java
    코딩
    자바
    오픈소스
    시뮬레이션
    게임개발
    코테
    트러블슈팅
    비트마스킹
    유니티
    우아한테크코스
    contribute
    합격
    개발자
    개발
    github
    프리코스
    백준
    8기
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
노을을
[JAVA] 2870-수학숙제 🩶4 : 문자열을 Integer.parseInt()로 형변환하려면 int형이 담을 수 있는 문자열 길이여야 가능하다.
상단으로

티스토리툴바