[Java] BufferedReader, StringTokenizer 클래스 사용방법, 백준 4344번 문제 풀이

    자바로 알고리즘 문제를 풀 때 Scanner 클래스를 사용하면 편리하나 속도가 느리다는 단점이 있다. 그래서 Scanner 대신에 버퍼를 사용하는 BufferedReader 클래스를 사용하여 알고리즘 문제를 풀면 시간복잡도 효율성에서 유리하다.

    BufferedReader, StringTokenizer 클래스 사용예제

    public class StringRepeat {
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    
            StringTokenizer st = new StringTokenizer(br.readLine()); //공백단위로 읽어드릴수 있는 라인 추가
            int c = Integer.parseInt(st.nextToken()); //한줄에서 공백 단위로 읽음
            int d = Integer.parseInt(st.nextToken()); //한줄에서 공백 단위로 읽음
            System.out.println(c + " " + d);
    
            st = new StringTokenizer(br.readLine(),","); // , 단위로 읽어드릴수 있는 라인 추가
            int e = Integer.parseInt(st.nextToken()); //한줄에서 , 단위로 읽음
            int f = Integer.parseInt(st.nextToken()); //한줄에서 , 단위로 읽음
            System.out.println(e + " " + f);
        }
    }
    

    BufferedReader로 라인을 읽고 그 라인에서 특정 문자열로 읽어드릴 수 있으려면 StringTokenizer 클래스를 사용해야 한다. new StringTokenizer(br.readLine)) 하면 라인을 읽어드릴 수 있고 nextToken()으로 공백단위로 읽어드릴 수 있다.

     

    Scanner 클래스에 비해서 사용이 힘든점은 반드시 throws IOException을 해줘야 하고, nextToken()으로 읽어드릴 때는 String으로 밖에 읽어드릴 수 없어 정수로 읽고 싶을 때는 Integer.parseInt()로 숫자로 된 문자열을 숫자형으로 형변환 시켜줘야 한다.

     

    라인 한줄을 읽고 다음 라인을 읽고 싶을 때는 new StringTokenizer(br.readLine()) 을 추가해야 하고 특정 문자열 단위로 읽고 싶을 때는 new StringTokenizer(st.nextToken(), 특정문자열)) 뒤에 인자를 추가하면 된다. (default는 공백이다.)

     

     

    만약에 공백단위로 한 줄을 다 읽고 싶다면 hasMoreTokens()를 사용하면 된다.

    StringTokenizer st = new StringTokenizer(br.readLine()); //공백단위로 읽어드릴수 있는 라인 추가
    while(st.hasMoreTokens()) {
        System.out.println(st.nextToken());
    }
    

     

     

    백준 4344번 문제풀이 https://www.acmicpc.net/problem/4344

    BuffferedReader와 StringTokenizer를 통해서 문제를 풀었다. 

    public class AboveAverage {
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            StringTokenizer st = new StringTokenizer(br.readLine());
    
            LinkedHashMap<ArrayList<Integer>, Double> hashMap = new LinkedHashMap<ArrayList<Integer>, Double>();
    
            int C = Integer.parseInt(st.nextToken());
    
            //테스트케이스
            for (int i = 0; i < C; i++) {
                st = new StringTokenizer(br.readLine());
                ArrayList<Integer> al = new ArrayList<>();
                //학생수
                int stuCnt = Integer.parseInt(st.nextToken());
    
                //학생수만큼 스코어 입력
                for(int j =0; j<stuCnt; j++) {
                    int score = Integer.parseInt(st.nextToken());
                    al.add(score);
                }
    
                hashMap.put(al, 0.0);
            }
    
            new AboveAverage().solve(hashMap);
        }
        public void solve(LinkedHashMap<ArrayList<Integer>, Double> hashMap) {
            int sum = 0;
            double average = 0;
    
            for (ArrayList<Integer> al : hashMap.keySet()) {
                for (Integer i : al) {
                    sum += i;
                }
                average = (double)sum/al.size();
                hashMap.put(al, average);
                sum = 0;
            }
            int cnt = 0;
            for (ArrayList<Integer> al : hashMap.keySet()) {
                for (Integer i : al) {
                    if ((double)i > hashMap.get(al)) {
                        cnt++;
                    };
                }
    
                double result = (double)cnt  / al.size() * 100.0;
                //System.out.println(Math.round(result * 1000) / 1000.0 + "%");
                System.out.printf("%.3f%%\n", result);
                cnt = 0;
            }
        }
    }

    테스트케이스 C의 값만큼 for문을 돌리고 for문이 실행될 때마다.

    st = new StringTokenizer(br.readLine(); 을 통해서 한줄을 읽고 그 한줄을 공백 단위로 짜른 배열을 가져온다.

    그리고 공백단위로 짤라진 값을 st.nextToken() 함수로 데이터를 가져와 리스트에 담는다.

    댓글

    Designed by JB FACTORY