I/O 와 Stream
I/O
- 데이터는 한 쪽에서 주고 한 쪽에선 받음.
- 이때 입력과 출력의 끝 단 => 노드, node
- 두 노드를 연결하고 데이터를 전송할 수 있는 개념 => 스트림, Stream
- 스트림은 단방향 통신, 하나의 스트림으로 입/출력 동시에 처리 불가..
Node stream
- node에 연결
- byte? char? => ##Stream, ##er
- 입력? 출력? => InputStream, OutputStream / Reader, Writer
- 노드 타입에 따라 => 키보드, 모니터, File, ByteArray, Pipe 등등...
- 최종 노드 스트림.
InputStream
- read()
- byte 하나를 읽어서 int로 반환.
- 더 이상 읽을 값 없으면 -1 리턴
- read(byte b[])
try - catch 필요.
끝나면 close. 또 try - catch.
try 안에 선언하면 자동으로 반납해 줌.
OutputStream..
Writer..
File
- 가장 기본적 입출력 장치 중 하나.
- '파일'과 '디렉토리'를 다루는 클래스
- 메서드 명
- File()
- createNewfile()
- ...
- 파일 '내용' 작성은 stream에서.
절대경로 / 상대경로
절대경로 => 프로젝트와 무관하게 파일을 읽을 때.
상대 경로
- '.' 은 프로젝트이 실행되는 경로이다.
-----
보조스트림.
- 다른 스트림에 부가적인 기능을 제공하는 스트림
- 노드 스트림은 단순 byte, char의 전달
- 보조스트림은 '부가 기능' 수행
- 문자 set 변환
- Buffering
- 기본 데이터 형의 전송
- 객체 입출력
- 스트림 체이닝, stream chaining
- 필요에 따라 여러 보조 스트림을 연결해서 사용 가능
보조 스트림 종류
- byte 스트림을 char 스트림으로
- 버퍼링을 통한 속도 향상
- BufferedReader..!
- BufferedWriter..!
- 객체 전송
사용할 스트림의 결정 과정
- 노드가 무엇인가
- 타입은 문자열? 바이트?
- 방향이 무엇인가
- 추가 기능이 필요한가
InputStreamReader & OutputStreamReader
Bufferd 계열
- BufferedInputStream
- 기본빵이 빠르다.
보조 스트림 활용
- 객체 직렬화, serialization
- 객체를 연속적인 데이터로 변환.
- 반대는 역 직렬화, deserialization
- 직렬화 되기 위한 조건
- Serializable 인터페이스 구현
- 클레스의 모든 멤버가 Serialization 구현
- 'transient' 선언 시 직렬화에서 제외.
자바의 i/o는 무지막지하게 느림.
-1은 모든 비트가 1.
read()에서 -1(11111111)이 들어오면 종료
- byte를 읽고 int로 반환하기에 중간에 끊길일은 없다.
UTF - 8
한글 3byte.
UTF - 16 (java)
0x80보다 크면 더 읽어들임.
-----
BufferedReader().read() 만 사용..
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine();
StringTokenizer st = new StringTokenizer(s," "); // 두 번째 인자 없으면 " "로 봄.
String s1 = st.nextToken();
int n1 = Integer.parseInt(s1);
int n2 = Integer.parseInt(st.nextToken());
-----
Lambda, 람다
- 함수적 프로그래밍의 형태로 재사용 가능한 코드 블록
- 익명 메소드. anonymous inner class
- 함수를 지원하는 건 아니고 functional 인터페이스를 전달.
타겟 타입과 @FunctionalInterface
- Lambda 식이 할당되는 인터페이스를 Lambda 식의 타겟 타입이라 함.
- 타겟 타입은 'abstract 메서드는 반드시 하나만 존재'해야 함.
- default, static은 무관.
(type variable_name[,...]) -> {실행문;};
생략 가능한 부분 많음.
functionalInterface / anonymous (객체)
- 'this' 가 가리키는 게 다름.
백트래킹
모든 가능성을 시도하는 게 아닌 후보군을 구성한 뒤 문제의 조건을 만족하는 지 여부를 검사하며 해답을 찾아감.
보통 재귀적으로 구현되며, 각 단계에서는 해결책 후보군 중 하나를 선택. 이 선택이 문제의 조건을 만족하는지 검사. 조건을 만족하지 않는다면 이전 단계로 돌아가 다른 후보군 선택. 이 과정 반복.
완전탐색과 유사하지만, 가능성이 없는 노드를 버림으로 대규모 문제를 효과적으로 해결할 수 있음.
하지만 구현이 어렵고 코드가 복잡해질 수 있음. 또한, 최악의 경우 모든 경로를 탐색해야 할 수 있음.
대부분의 시간복잡도가 지수 시간이므로 가능한 한 불필요한 탐색을 줄어야 함.
N과 M, 모든 순열, n-queens 등등 풀이..