본문 바로가기

카테고리 없음

Do it! 알고리즘 입문: 자바 편 (22)[책리뷰 & Book review]

by Life & study 2024. 2. 5.
반응형

 

 

 

[N]과 [N+1]을 한 이유는 무엇인가?

배열의 인덱스는 보통 0부터 시작합니다. 따라서, 배열의 크기를 N으로 정의하면, 

배열의 인덱스는 0부터 N-1까지가 됩니다.

 

 이 경우, 배열의 첫 번째 원소는 array [0], 마지막 원소는 array [N-1]로 접근할 수 있습니다.

그러나 때때로, 문제의 조건이나 특정 알고리즘의 편의성을 위해 배열의 인덱스를 1부터 시작하게 만들고 싶을 때가 있습니다. 이럴 때 배열의 크기를 N+1로 정의하고, 실제 데이터는 1번 인덱스부터 N번 인덱스까지 저장합니다. 이 경우, 배열의 첫 번째 원소는 array [1], 마지막 원소는 array [N]으로 접근할 수 있습니다.

따라서, N과 N+1로 배열을 정의하는 것의 주요 차이점은 배열의 인덱스 시작점이다. N을 사용하면 인덱스는 0부터 시작하고, N+1을 사용하면 인덱스는 1부터 시작합니다. 앞서 설명한 것처럼, 이는 문제의 조건이나 알고리즘의 편의성에 따라 선택할 수 있습니다.




 

sum[i] = sum [i-1] + numbers [i]에 대해서 

sum [i] = sum [i-1] + numbers [i];에서 i-1을 사용하는 이유는 **부분합(Prefix Sum)**을 계산하기 위함입니다. 

sum [i]는 배열의 첫 번째 요소부터 i번째 요소까지의 합을 저장합니다.

따라서 start부터 end까지의 합을 구하려면, end까지의 합(sum [end])에서 start - 1까지의 합(sum [start - 1])을 빼야 합니다. 이렇게 하면 start부터 end까지의 합만 남게 됩니다.

예를 들어, numbers 배열이 [1, 2, 3, 4, 5]이고, start가 2, end가 4라면, start부터 end까지의 합은 2 + 3 + 4 = 9입니다.

 이는 sum[4] - sum [2 - 1] = 10 - 1 = 9와 같습니다.

즉, i-1을 사용하는 것은 배열의 특정 범위의 합을 빠르게 계산하기 위한 것이며,

배열의 인덱스가 0부터 시작하는 것과는 별개의 이유입니다. 

 

 

 

 

 

 

    int N = sc.nextInt();
        int M = sc.nextInt(); 은 예제 입력 1에 대해서

 

1.int N = sc.nextInt(); int M = sc.nextInt();
사용자로부터 두 개의 정수 N과 M을 입력받습니다. 여기서 N은 숫자의 개수, M은 구하려는 구간의 개수를 나타냅니다.
예제 입력에서는 N은 5, M은 3입니다.

 

2.int[] numbers = new int [N]; int [] sum = new int [N];

입력받은 숫자들을 저장할 배열 numbers와 각 인덱스까지의 누적합을 저장할 배열 sum을 생성합니다.

 

3.for(int i = 0; i < N; i++) { numbers [i] = sc.nextInt(); if (i == 0) { sum [i] = numbers [i]; } else { sum[i] = sum[i-1] + numbers[i]; } }
사용자로부터 N개의 숫자를 입력받아 numbers 배열에 저장하고, 각 인덱스까지의 누적합을 sum 배열에 저장합니다.
예제 입력에서는 숫자들은 5, 4, 3, 2, 1이고, 이들의 누적합은 각각 5, 9, 12, 14, 15입니다.

 

4.for(int i = 0; i < M; i++) { int start = sc.nextInt() - 1; int end = sc.nextInt() - 1; if(start == 0) { System.out.println(sum [end]); } else { System.out.println(sum[end] - sum [start - 1]); } }
사용자로부터 M개의 구간을 입력받아, 각 구간의 합을 출력합니다.
예제 입력에서는 구간들은 (1, 3), (2, 4), (5, 5)이고, 이들의 합은 각각 12, 9, 1입니다.


코드

plain

시간 -------->
| 입력: N=5, M=3
| numbers = [5, 4, 3, 2, 1], sum = [5, 9, 12, 14, 15]
| 입력: (start=1, end=3), 출력: 12
| 입력: (start=2, end=4), 출력: 9
| 입력: (start=5, end=5), 출력: 1


 시간이 진행됨에 따라 사용자의 입력을 받고, 그에 따라 배열을 갱신하고, 결과를 출력하는 과정을 보여줍니다. 이 도식은 코드의 실행 순서와 결과를 시간 순서대로 나타낸 것입니다.

 

 

 

 

 

 

 Scanner와 BufferedReader는 어떤 것인가

 

 Scanner와 BufferedReader는 둘 다 자바에서 사용자의 입력을 받아오기 위한 클래스입니다. 

그러나 두 클래스의 작동 방식과 특성은 다르기 때문에 사용자의 요구에 따라 적절하게 선택하여 사용해야 합니다.

Scanner 클래스 Scanner 클래스는 자바에서 제공하는 가장 간단한 방법으로 입력을 처리할 수 있습니다. 

이 클래스는 공백, 탭, 줄 바꿈 등을 기준으로 토큰을 분리하여 입력을 처리합니다. 

Scanner는 다양한 타입의 입력 처리가 가능하며 사용법 역시 간단합니다.


java

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        System.out.println(s);
    }
}


장점:

사용법이 간단하며 다양한 데이터 타입을 처리할 수 있습니다.
정규식을 사용하여 입력을 처리할 수 있습니다.

 

단점:

입력을 처리하는 속도가 느립니다.
버퍼 크기를 조절할 수 없습니다.
BufferedReader 클래스 BufferedReader 클래스는 문자 입력 스트림에서 문자를 버퍼링 하여 문자, 배열 및 라인의 효율적인 읽기를 가능하게 합니다. BufferedReader는 크기가 큰 입력을 처리할 때 효과적입니다.

 


java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s = br.readLine();
        System.out.println(s);
    }
}


장점:

큰 입력을 빠르게 처리할 수 있습니다.
버퍼의 크기를 조절할 수 있습니다.
단점:

사용법이 복잡하며 오직 문자열만 처리할 수 있습니다.
예외 처리가 필요합니다.
아래는 두 클래스의 작동 방식을 도식화한 그림입니다:

[ 사용자 입력 ]  -->  [ Scanner / BufferedReader ]  -->  [ 프로그램 ]
사용자의 입력은 Scanner나 BufferedReader를 통해 프로그램에 전달되며, 프로그램은 이를 처리하여 원하는 결과를 출력합니다. 

이러한 과정에서 Scanner는 입력을 토큰화하여 처리하며, BufferedReader는 버퍼를 이용하여 입력을 처리합니다.



 

 

 

 

 

Scanner는 입력을 토큰화한다??

 

Scanner의 입력 토큰화 Scanner는 입력을 토큰화하여 처리합니다. 

이는 입력된 데이터를 공백이나 개행문자('\n') 등을 기준으로 분리하여 처리하는 것을 말합니다. 

다음의 예제는 Scanner를 이용하여 문자열을 입력받아 공백으로 분리하여 출력하는 코드입니다.
java

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String s = sc.next();
            System.out.println(s);
        }
    }
}

 

 

 

 

 

 

 

반응형

댓글