알고리즘

[알고리즘] 003 구간합 BufferedReader

IronAreum 2023. 8. 19. 15:18
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