[TIL_Algorithm] 구간 합 구하기 공식, StringTokenizer

effiRin·2022년 7월 21일
0
post-thumbnail

<Do it! 알고리즘 코딩테스트 - 자바 편>
문제 3 - 백준 11659번 (https://www.acmicpc.net/problem/11659)


문제풀기


💡 베스트답

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

public class Main {

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

    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        int n = Integer.parseInt(st.nextToken());  // 데이터의 개수
        int m = Integer.parseInt(st.nextToken());  // 물어볼 개수

        long[] sum = new long[n + 1]; // 인덱스 1부터 쓰기 위해서

        st = new StringTokenizer(br.readLine());    // 새로운 인스턴스 만들어서 두 번째 줄 입력 받음

        // 인덱스 1부터 - sum[0]은 기본값 0으로 들어감
        System.out.println(sum[0]);

        for (int i = 1; i < n+1; i++) {
            sum[i] = sum[i-1] + Integer.parseInt(st.nextToken());
        }

        for(int a = 0; a < m; a++) {
            st = new StringTokenizer(br.readLine());

            int i  = Integer.parseInt(st.nextToken());
            int j  = Integer.parseInt(st.nextToken());

            System.out.println(sum[j] - sum[i - 1]);

        } // for
    }// main
}
  • '구간 합' 구할 때 쓰면 좋은 공식
인덱스12345
배열 num[ ] 54321
합 배열 Sum[ ]59121415
  • 합 배열 공식 : sum[i] = sum[i-1] + num[i]
  • 구간(i~j) 합 공식 : sum[j] - sum[i-1]

▶ 주의할 점
인덱스 0이 아닌 '1'부터 시작해야 함. (sum[i-1] 때문에)


1회차 푼 답

package com.yerin.BaekJoon.DoIt;

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

public class SumOfSection {

    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        String[] str = br.readLine().split(" ");
        int n = Integer.parseInt(str[0]);
        int m = Integer.parseInt(str[1]);

        int[] nums = new int[n];
        int[] sum = new int[n];

        String[] temp = br.readLine().split(" ");

        for (int i = 0; i < n; i++) {
            nums[i] = Integer.parseInt(temp[i]);

            if(i != 0){sum[i] = sum[i - 1] + nums[i];}
            else {sum[i] = nums[i];}
        } // for

        for(int a = 0; a < m; a++) {
            String[] section = br.readLine().split(" ");

            int i  = Integer.parseInt(section[1])-1;
            int j  = Integer.parseInt(section[0])-2;

            if (i != j && j >= 0){
                System.out.println(sum[i]-sum[j]);
            }
            else if(j == -1){
                System.out.println(sum[i]);
            }
            else {
                System.out.println(nums[i]);
            }
        } // for

    }// main
}

  • 처음엔 split() 메서드를 썼는데 리턴타입이 String[] 배열이라서, 새로운 배열을 만들어서 작업을 수행했다.
    그러다보니 불필요한 작업 과정이 발생했고, 메모리도 비효율적으로 쓰게 됨.
    → StringTokenizer를 쓰면 String 으로 반환해주기 때문에 배열을 반환해줄 때 발생하는 불필요한 코드들을 줄일 수 있었음.
  • 또한 인덱스가 0일 때 발생하는 경우를 일일이 if - else문을 써주며 처리해줌. → 인덱스 0은 그냥 기본값 0으로 놔두고, 인덱스 1부터 써주면 코드가 훨씬 깔끔하게 쓰일 수 있었음


오답 노트

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

public class Main {

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

    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        int n = Integer.parseInt(st.nextToken());  // 데이터의 개수
        int m = Integer.parseInt(st.nextToken());  // 물어볼 개수

//        int[] nums = new int[n];    // 사실상 필요없음 -> 합 배열만 구하면 됨
        long[] sum = new long[n + 1]; // 인덱스 1부터 쓰기 위해서

		// 새로운 인스턴스 만들어서 두 번째 줄 입력 받음
        st = new StringTokenizer(br.readLine());    
        

// 인덱스 0부터 쓰려면 이렇게 써야했던 걸 인덱스 1부터 쓰면 다음과 같이 간단해짐...
//        for (int i = 0; i < n; i++) {
//            nums[i] = Integer.parseInt(st.nextToken());
//
//            if(i != 0){sum[i] = sum[i - 1] + nums[i];}
//            else {sum[i] = nums[i];}
//        } // for

        // 인덱스 1부터 - sum[0]은 기본값 0으로 들어감
        System.out.println(sum[0]);

        for (int i = 1; i < n+1; i++) {
            sum[i] = sum[i-1] + Integer.parseInt(st.nextToken());
        }

        for(int a = 0; a < m; a++) {
            st = new StringTokenizer(br.readLine());   //

            int i  = Integer.parseInt(st.nextToken());
            int j  = Integer.parseInt(st.nextToken());

            System.out.println(sum[j] - sum[i - 1]);

        } // for
    }// main
}



공부하기

  • StringTokenizer와 split() 메서드에 대한 자세한 공부
    아래 링크 참고

Java-StringTokenizer와-Split-메서드-언제-써야할까


profile
모종삽에서 포크레인까지

0개의 댓글