[알고리즘] 003 구간합 BufferedReader
코딩테스트를 처음칠때 약간 당황했던건
문제에서 주어진 입력값을 어떤형식으로 받아야 하는가 였다.
여러문제를 많이 접해보면 자연스럽게 알게되겠지만
그렇지 못했던 지난날을 되돌아보며..
package Quiz;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.Scanner;
import java.util.StringTokenizer;
public class Q003_구간합구하기 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//수 N개가 주어졌을때 i번째부터 j번째 수까지의 합 구하기(제한시간: 0.5초)
//입력값
//1: 수의 개수 N (1 <= N <= 100000)
//2. 합을 구하는 횟수 M (1 <= M <= 100000)
//3. M개의 줄어 합을 구해야하는 구간 i와 j
//분석하기 : 구간마다 합을 구하면 시간이 너무 소요되므로, 구간합을 이용.
//합 배열 공식 : A:배열, S:합배열 일때
//S[i] = S[i-1] + A[i]
//구간합 공식 : Q(i,j) = S[j] - S[i-1]
//질의1(1,3) : S[3] - S[0];
//질의2(2,4) : S[4] - S[1];
//질의3(5,5) : S[5] - S[4];
/* 슈도코드 작성
*
* suNo(수의 개수), quizNo(질의 횟수) 저장하기
*
* int S[](구간합) = new [수의개수]; // 구간합 초기화
*
* for(수의 개수){
* 합 배열 생성하기(S[i] = A[i] + S[i-1];
* }
*
* for(M(질의횟수)){
* 질의범위 받기(i,J)
* 구간 합 출력하기(S[j] - S[i-1])
* }
* */
//입력값 받기
//Scanner sc = new Scanner(System.in); //아래 더 큰블록으로 읽는 BufferdReader로 한번에 받자!
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
//한번에 받은대상 자르기
//StreamTokenizer st = new StreamTokenizer(bf.readLine());
StringTokenizer st = new StringTokenizer(bf.readLine());
int suNo = Integer.parseInt(st.nextToken()); //수의 개수
int quizNo = Integer.parseInt(st.nextToken()); //질의 개수
int sum[] = new int[suNo+1];
st = new StringTokenizer(bf.readLine()); //숫자배열 읽기
//합배열 생성하기
for(int i=0; i <= suNo; i++) {
if(i==0) {
sum[i] = 0;
}else {
sum[i] = sum[i-1] + Integer.parseInt(st.nextToken()); //구간합
}
}
//질의횟수만큼 구간합 구하기
for(int ii=0; ii<quizNo; ii++) {
st = new StringTokenizer(bf.readLine()); //구간읽기
//질의범위 받기
int i = Integer.parseInt(st.nextToken());
int j = Integer.parseInt(st.nextToken());
//구간합 출력하기
System.out.println( sum[j]-sum[i-1] );
}
}
}
띄어쓰기가 되어있는 값들을 입력받을때 도움이 되는 자바함수에 대해 메모하기
참고링크 : https://rlakuku-program.tistory.com/33
[Java] 빠른 입출력을 위한 BufferedReader, BufferedWriter, StringTokenizer, StringBuilder
BufferedReader / BufferedWriter BufferedReader와 BufferdWriter는 버퍼를 사용하여 읽기와 쓰기를 하는 함수이다. 버퍼를 사용하지 않는 입력은, 키보드의 입력이 키를 누르는 즉시 바로 프로그램에 전달된다.
rlakuku-program.tistory.com
BufferedReader / BufferedWriter
버퍼를 사용하여 읽기와 쓰기를 하는 함수.
버퍼가 가득차거나 혹은 개행문자 나타나면 버퍼의 내용을 한번에 프로그램에 전달한다. (키보드의 입력이 키를 누르는 즉시 바로프로그램에 전달되는 형식과 다르게)
- Scanenr
띄어쓰기와 개행문자를 경계로 입력값을 인식 한다.
원하는 타입으로 입력받을수 있음. nextInt() , next() 등.
단, 버퍼사이즈가 1024 char이기 때문에 많은 입력을 필요로 할 경우에는 성능상 좋지못한 결과를 불러온다. (주의)
- BufferedReader
Scanner와 달리, BufferedReader는 입력받은 데이터가 String 형식으로 고정되어 있고, 개행문자만 경계로 인식한다. (Scanner보다 속도빠름)
또한 버퍼사이즈도 8192 char(16,384 byte)이기 때문에 입력이 많을때 유리함.
- BufferedReader 사용법
//throws IOException 처리필요 or try/catch 처리
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 선언
String s = br.readLine(); //한줄씩 읽기
int i = Integer.parseInt(br.readLine()); //String 외 다른 형으로 입력받을경우 형변환 필요
}
- 데이터 가공
BufferedReader를 통해 읽어론 데이터는 개행문자 단위(Line 단위)로 나누어진다.
만약 공백단위로 데이터를 가공하고자 하면 따로 처리가 필요하다.
이때 사용하는것이 StringTokenizer 나 String.split()함수이다.
// StringTokenizer
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken()); //nextToken : readLine()을 공백단위로 구분하여 순서대로 호출가능
int M = Integer.parseInt(st.nextToken());
// String.split() 함수
String arr[] = s.split(" ");
StringTokenizer의 nextToken() 함수를 사용하면, readLine()로 입력받은 값을 공백 단위로 구분하여 순서대로 호출 할수있다.
String.split() 함수를 사용하면, 배열에 공백단위로 끊어 데이터를 저장하여 사용할수있다.
- BufferedReader 클래스의 메인 함수들
Modifier and Type | Method and Description |
void | close() 입력 스트림을 닫고, 사용하던 자원을 해제 |
void | mark(int , readAheadLimit) 스트림의 현재 위치를 마킹 |
int | read() 한 글자만 읽어 정수형으로 반환 (e.g ,'3'을 읽어 정수형인 (int)'3' = 51로 반환) |
String | readLine() 한 줄을 읽음 |
boolean | ready() 입력 스트림이 사용할 준비가 되었는지 확인 (1이 준비 완료) |
- StringBuilder 사용법
StringBuilder sb = new StringBuilder();
sb.append("a");
sb.append("b").append(" ");
sb.append("c").append("\n");
StringBuilder 주요 메소드
- StringBuilder append(String s) : StringBuilder 뒤에 값을 붙임
- StringBuilder delete(int start , int end) : 특정 인덱스부터 인덱스까지를 삭제
- StringBuilder insert(int offet, any primitive of a char[]) : 문자를 삽입함
- StringBuilder replace(int start , int end , String s) : 일부를 String 객체로 치환
- StringBuilder reverse() : 순서를 뒤집음
- StringBuilder setCharAt(int index , char ch) : 주어진 문자를 치환
- StringBuilder indexOf(String s) : 값이 어느 인덱스에 들어있는지 확인
- StringBuilder subString(int start, int end) : start와 end 사이의 값을 잘라옴.