본문 바로가기
알고리즘

[알고리즘] 003 구간합 BufferedReader

by IronAreum 2023. 8. 19.
728x90

코딩테스트를 처음칠때 약간 당황했던건

문제에서 주어진 입력값을 어떤형식으로 받아야 하는가 였다.

 

여러문제를 많이 접해보면 자연스럽게 알게되겠지만

그렇지 못했던 지난날을 되돌아보며..

 

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


 

 

 

728x90

 

 

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 사이의 값을 잘라옴.
728x90