본문 바로가기
Algorithm/Baekjoon

[백준] 1152번 : 단어의 개수

by unknownomad 2022. 3. 21.

https://www.acmicpc.net/problem/1152

 

1152번: 단어의 개수

첫 줄에 영어 대소문자와 공백으로 이루어진 문자열이 주어진다. 이 문자열의 길이는 1,000,000을 넘지 않는다. 단어는 공백 한 개로 구분되며, 공백이 연속해서 나오는 경우는 없다. 또한 문자열

www.acmicpc.net



주의점

  • 문자열 앞뒤에 공백이 있을 수 있음 = 공백의 개수 대로 숫자를 세면 예외 발생할 수 있음

구현 방법

1. 입력

1.1. Scanner & BufferedReader

  • 많이 쓰는 입력 방식

1.2. System.in.read()

  • 기본 입력 스트림
  • buffer 사용 X
  • 원시 입력 형태로 문자 하나씩 읽어들여 문자가 공백인지 아닌지에 따라 count++ 하기

 

2. 공백 기준으로 분리

2.1. 문자열을 읽은 후 charAt() 통해 공백 검사

2.2. StringTokenizer

2.3. split()

2.3.1. 주의점

  • 공백만 입력받을 경우 단어의 개수는 0 이므로 결과값 = 0 이 정답이지만,
    split() 함수로 출력할 시 결과값 = 1 이 나옴

2.3.2. String 클래스의 split() 함수와 빈 문자열

String s = scan.nextLine(); //= BufferedReader.readLine()

s = " "; //입력값 : 공백(" ") = 공백 문자열
s.trim(); //앞뒤 공백 제거 : trim() or strip()
s = ""; //빈 문자열
//s = 0의 길이를 가진 String 변수
//빈 문자열 "" != null

//-----예시-----
String a = ""; //빈 문자열이나, 실제값(빈 값)을 갖는 인스턴스화된 문자열
String b = null; //할당 자체가 되지 않음 = 인스턴스화 되지 않아 참조하는 것 자체가 없음
//-----예시-----

String[] str = s.split(" ");
//split(): 매칭되는 정규식이 없으면 자기 자신을 반환함
if(off == 0) {
    return new String[] {this};
}
//this = trim() or strip() 통해 공백 제거한 String s = "";

/*
split(" "); 실행해도 공백(" ")에 매칭되는 문자열 존재 X
return new String[] {this}; 실행됨
this = 자기 자신이 담고 있떤 빈 문자열 = "";
➡ String[] spl 배열 : index 0 에 빈 문자열 1개가 반환됨
= spl 배열의 길이 = 1
*/

String[] spl = s.split(" ");
spl[0] = "";
spl.length = 1;

 

2.3.3. split() 으로 문제 풀려면

  1. trim() or strip() 으로 앞뒤 공백 삭제
  2. 해당 문자열이 빈 문자열인지 확인
  3. 빈 문자열이면 0 출력 / 그 외에는 split() 함수 사용해 String[] 배열로 반환 후 배열의 길이 출력

 


풀이

1. Scanner + StringTokenizer()

import java.util.Scanner;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) {
    
        Scanner in = new Scanner(System.in);
        String S = in.nextLine();
        in.close();
 
        //공백을 기준으로 나눈 토큰들을 st 에 저장
        StringTokenizer st = new StringTokenizer(S, " ");
		
        //countTokens(): 토큰의 개수 반환
        System.out.println(st.countTokens());	
    }
}

 

2. BufferedReader + StringTokenizer()

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;
 
public class Main {
    public static void main(String[] args) throws IOException {
    
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        System.out.println(st.countTokens());
    }
}

 

3. System.in.read()

import java.io.IOException;
 
public class Main {
    public static void main(String[] args) throws IOException {

        int str;
        int preStr = 32; //= 공백
        int cnt = 0;
		
        while(true) {
            str = System.in.read();
            
            //preStr 추가 조건 없으면 첫 문자와 마지막 문자가 공백일 경우 cnt +1 됨
            if(str == 32) { //입력 받은 문자가 공백이면
                if(preStr != 32) { //이전 문자가 공백이 아니면
                    cnt++;
                }
            } else if(str == 10) { // 입력 받은 문자가 개행이면("\n")
                if(preStr != 32) { // 이전의 문자가 공백이 아니면
                    cnt++;
                    break;
                }
            }
            preStr = str;
        }
        System.out.println(cnt);
    }
}

성능

  1. System.in.read()
  2. BufferedReader + StringTokenizer()
  3. Scanner + StringTokenizer()

 


출처 : https://st-lab.tistory.com/65

댓글