예전에 사놓았던 알고리즘 책을 공부하며 예제 및 문제로 나오는 백준 문제를 접해보았습니다.
필자는 알고리즘 사이트 중 프로그래머스를 이용하는데 백준은 너무 어색하네요.(사실 예전에 몇문제 풀고 어색해 프로그래머스로 넘어감...)
입출력도 맞춰야 하고... 그래도 사놓은 책(DO it 코딩테스트) 제대로 공부하기위해 처음부터 하나하나 정리해가며 백준에 적응해보려 합니다.ㅎㅎ
Scanner sc = new Scanner(System.in);
sc.next(); // String을 읽음. 단, 띄어쓰기 뒷부분은 읽지 않음
sc.nextLine(); // String을 읽음. 띄어쓰기를 포함하여 한 줄(Enter를 치기 전까지)을 읽음
sc.nextInt(); // int를 읽음
sc.nextBoolean(); // boolean 을 읽음
sc.nextByte(); // byte 를 읽음
sc.nextShort(); // Short 를 읽음
sc.nextLong(); // Long 를 읽음
sc.nextFloat(); // Float 를 읽음
sc.nextDouble(); // Double 를 읽음
public static void main( String[] args ) {
Scanner sc = new Scanner( System.in );
String firstName = sc.next();
String lastName = sc.next();
int age = sc.nextInt();
System.out.println( firstName + lastName + age );
sc.close();
}
입력 : first last 111
출력 : firstlast111
위 예제를 보면 스페이스바로 구분된 토큰들은 first
, last
, 111
입니다.
공백문자는 사라지지 않습니다.
사용자가 입력장치를 통해 어떠한 데이터들을 입력할 때, 컴퓨터는 공백문자까지도 버퍼2에 저장합니다.
2 : 하나의 장치에서 다른 장치로 데이터를 전송할 경우에 양자간의 데이터 전송 속도나 처리 속도의 차를 보상하여 양호하게 결합 할 목적으로 사용하는 기억영역.(임시저장공간)
즉, 사용자가 입력한 스페이스, 탭, 엔터, ..등등 입력값과 함께 버퍼에 저장되고, 다른 곳에서 읽어들이기 전까지 버퍼에 남아있습니다.
그럼 nextLine()은?
nextLine()
메서드는 Enter
단위로 읽고, 나머지 메서드들은 Token(토큰)
단위로 읽습니다.
nextLine()
는 \n
을 포함해서 읽어들이고, 나머지 메서드들은 \n
뿐만 아니라 다른 공백문자도, 제외해서 읽어들입니다.
nextLine()
는 \n
을 버려서 리턴 하고, 나머지 메서드들은 애초애 공백문자를 제외해서 읽어들였으므로 반환값도 공백문자가 제ㄷ외된 상태로 반환합니다.
public static void main( String[] args ) {
Scanner sc = new Scanner( System.in );
String test = sc.next();
System.out.println( "test : " + test );
sc.close();
}
Token(토큰) 단위로 읽는다.
입력값을 읽을 때, 공백문자를 제외해서 읽습니다.
반환할 때 공백문자를 제외한 값을 반환합니다.
위 예제에서 사용자가 "test_(공백)" 을 입력하면 어떻게 출력될까요?
공백을 제외한 test 만 출력됩니다.
public static void main( String[] args ) {
Scanner sc = new Scanner( System.in );
String test = sc.nextLine();
System.out.println( "test : " + test );
sc.close();
}
Enter(엔터) 단위로 읽는다.
입력 버퍼에 저장되어있는 공백문자를 포함하는 한 줄을 읽습니다.
값을 반환할 때\n
(Enter) 를 버린 나머지를 반환합니다.
위 예제에 사용자가 "t e s t" 와 같은 공백이 포함되어 있는 문자를 입력하면 어떻게 될까요?
nextLine() 는 엔터단위로 읽기 때문에 "t e s t" 그대로 출력됩니다.
Scanner 와 달리 BufferedReader는 개행문자만 경계로 인식하고 입력받은 데이터가 String으로 고정된다.
Scanner는 자체 메서드로 데이터를 가공해 받을 수 있지만 BufferedReader는 따로 데이터를 가공해야한다.
어쩌면 입력받은 즉시 전송하는 Scanner가 더 효율적이라고 생각될 수 있겠지만
버퍼링 없이 전송하는 것은 CPU와의 성능 차이 때문에 버퍼를 사용하는 방식보다 속도에서 비효율적이라고 할 수 있다.
과일을 수확할 때, 하나의 과일을 딸 때마다 창고로 옮겨주는 것과
수확한 과일을 한 수레에 모아 한번에 창고로 옮겨주는 것의 효율 차이를 예로 들 수 있다.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine(); // 사용자의 입력
BufferedReader를 통해 읽어온 데이터는 개행문자로 나누어지기때문에 공백 단위로 데이터를 가동하고자 한다면 따고 가공 작업이 필요합니다.
// StringTokenizer
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
// String.split() 함수
String arr[] = s.split(" ");
StringTokenizer의 nextToken() 함수를 쓰면 readLine()을 통해 입력 받은 값을 공백 단위로 구분하여 순서대로 호출할 수 있다.
String.split() 함수를 사용하면, 배열에 공백단위로 끊어 데이터를 저장하여 사용할 수 있다.
일반적으로 출력을 할 때, System.out.println(""); 을 사용한다. 적은 양의 출력에서는 편리하고, 그렇게 큰 성능 차이 없이 사용할 수 있다. 하지만 우리가 늘 고려해야하는 경우는 양이 많을 경우이다. 많은 양의 출력을 할 때는, 입력과 동일하게 버퍼를 사용하는 것이 좋다.
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); _//_ 선언
String str = "abcdef"; _//_ 출력할 문자열
bw.write(s); _//_ 출력
bw.newLine(); _//_ 줄바꿈
bw.flush(); _//_ 남아있는 데이터 모두 출력
bw.close();
BufferedWriter는 System.out.println(""); 처럼 출력과 개행을 동시해 해주지 않기 때문에, 개행을 위해선
따로 newLine(); 혹은 bw.write("\n");을 사용해야한다. 그리고 BufferedWriter의 경우 버퍼를 잡아 놓았기 때문에 반드시 사용한 후에, flush()/ close()를 해주어야 한다. close()를 하게되면, 출력 스트림을 아예 닫아버리기 때문에 한번 출력후, 다른 것도 출력하고자 한다면 flush()를 사용하면 된다.