서론
요새 프로그래머스가 잠잠해져서 LeetCode 외에도 HackerRank라는 플랫폼에서도 코테문제를 풀고있는데, 얼른 플랫폼에 적응해서 적당한 난이도의 문제를 풀고 포스팅 하고 싶다
서론이 이상하게 흘러갔는데 여튼, 백준처럼 직접 입력받아 출력해야하는 포맷의 HackerRank인 만큼, 입출력에 대한 공부를 조금더 할 필요가 있었다.
BufferedReader / BufferedWriter
기존 입출력을 Scanner와 System.out을 활용하는 것에 익숙해져 있었고
요새는 코딩을 할 때, 파일 입출력 외에는 입출력을 사용하지 않아 거의 가물가물..
코테 문제를 풀 때, String값을 자주 바꿔줘야할 때 아래의 예시처럼, String에 직접 값을 추가하는 것 보다 StringBuffer의 append()를 활용하는 것이 성능 테스트 시 속도가 더 빠른 것을 경험한 적이 있다.
String str = "";
str += "a";
str += "pp";
str += "le";
StringBuffer str = new StringBuffer();
str.append("a");
str.append("pp");
str.append("le");
입력된 데이터가 버퍼를 거쳐 전달되어 데이터 처리 효율성이 높다. 즉 속도가 훨씬 빠르다. 그래서 많은 양의 데이터를 처리할 때 유리하며, 코테 문제에서도 StringBuffer을 사용하는 것이 더 좋다. 라고 하는 것이다.
BufferedReader의 기본 사용법은 아래와 같다.
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String str = bf.readLine();
int num = Integer.parseInt(bf.readLine());
입력 시에는 readLine()을 활용하며, 아래의 int 선언구와 같이 String이 아닌 다른 타입으로 사용 시 형변환이 필수적이다. 또한 예외처리가 필수적이며, IDE를 사용 시 readLine을 사용하다 보면 IOException에 대한 예외처리를 해달라고 컴파일 에러를 낸다. 말그대로 Input / Output에 대한 Exception이다.
또한 위의 예시에서처럼, Line단위로 구분을 짓기 때문에, 가공을 위해서 후처리를 해주어야 한다.
StringTokenizer st = new StringTokenizer(str);
int num1 = Integer.parseInt(st.nextToken());
int num2 = Integer.parseInt(st.nextToken());
String str[] = str.split(" ");
StringTokenizer에 입력받은 문자열을 넣어, nextToken()을 활용하여 입력받은 줄 단위의 문자열에서 공백 단위로 구분지어 순서대로 호출할 수 있다. 또한 split을 사용하는 것도 방법이 될 수 있다.
그리고, 버퍼를 사용하여 데이터를 읽기 때문에 버퍼에 남아있는 데이터를 소비하고 해제하여야 하며 이를 위해 close 메서드를 마지막에 사용해 주는 것이 좋다.
bf.close();
다음으로 BufferedWriter을 사용하는 예제이다.
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String str = "apple";
bw.write(str+"\n");
bw.flush();
bw.close();
우선 flush()와 close()가 눈에 띄는데, 객체 생성 시 새로운 버퍼가 생성되기 때문에, flush()를 사용하여 버퍼에 남아있는 데이터를 강제로 출력하고, 버퍼를 비워주어야하며, close()를 사용하여 버퍼를 닫고 리소스를 해제하는 후처리 작업이 동행되어야 한다.
예제
서론에서 언급했던 HackerRank 예제이다
import java.io.*;
import java.math.*;
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.regex.*;
import java.util.stream.*;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
class Result {
/*
* Complete the 'simpleArraySum' function below.
*
* The function is expected to return an INTEGER.
* The function accepts INTEGER_ARRAY ar as parameter.
*/
public static int simpleArraySum(List<Integer> ar) {
// Write your code here
}
}
public class Solution {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));
int arCount = Integer.parseInt(bufferedReader.readLine().trim());
List<Integer> ar = Stream.of(bufferedReader.readLine().replaceAll("\\s+$", "").split(" "))
.map(Integer::parseInt)
.collect(toList());
int result = Result.simpleArraySum(ar);
bufferedWriter.write(String.valueOf(result));
bufferedWriter.newLine();
bufferedReader.close();
bufferedWriter.close();
}
}
단순 배열안에 있는 모든 값을 더하는 문제였고 아래와 같이 해결함.
public static int simpleArraySum(List<Integer> ar) {
int answer = 0;
for(int i : ar){
answer += i;
}
return answer;
}
2023.04 ~ 백엔드 개발자의 기록
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!