[1152] Baek joon

문장을 입력받아서 공백 기준으로 split해서 배열의 length를 세어주는 간단한 문제라 생각했으나 디테일한 부분을 놓쳐 꽤 긴 시간 헤매서 정리해본다.
우선 Scanner의 next()와 nextLine()의 차이에 대한 내용을 까먹어서 next()로 배열을 자꾸 받으려고 시도하니 Index Length 오류가 발생했다..
참고로 next()는 공백 문자(스페이스, 탭, 개행 등)을 기준으로 다음 토큰을 읽어오기 때문에 “Hello World”를 하게 되면 Hello와 World가 각각의 변수에 들어간다. 즉, 사용자가 입력한 데이터를 공백 문자 전까지만 읽어오기 때문에 배열로 들어가는 게 아니다!!!! 단어 단위로 읽어온다.
반면, nextLine()은 개행문자(Enter)를 기준으로 한 줄 전체를 읽어 온다. 그렇기 때문에 nextLine().split(““)을 하게 되면 배열에 담기게 되는 것!
import java.beans.PropertyEditorSupport;
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
// 문자열 양 끝의 공백 제거 후 공백을 기준으로 나눔
String[] words = input.trim().split(" ");
// split(" ") 메서드는 주어진 문자열을 공백으로 나눌 때, 연속된 공백도 분리하여 빈 문자열을 생성한다.
// 즉, split을 공백으로 나누면은 문장의 첫 글자가 공백일 경우 "" 가 들어가게 됨.
words = removeEmptyStrings(words);
System.out.println(words.length);
}
private static String[] removeEmptyStrings(String[] words) {
int count = 0;
// 공백이 아닌 배열 값의 개수를 센다.
for (String s : words) {
if (!s.isEmpty()) {
count++;
}
}
// 공백이 아닌 개수만큼의 크기의 배열을 만든다.
String[] result = new String[count];
int index = 0;
for (String s : words) {
if (!s.isEmpty()) { // 공백이 아닐 때 result에 s를 더함.
result[index++] = s;
}
}
return result;
}
}
또 한가지 간과한 것은 split(“ “)을 하게되면 주어진 문자열을 공백으로 나누게 되는데, 연속된 공백도 분리하여 빈 문자열을 생성한다. 즉, 입력된 문자열을 공백으로 나누어 배열로 만들 때 공백이 연속되어 있으면 그 사이에 빈 문자열이 생성된다.
예를 들어 “Hello World”를 split(“ “)을 하게되면 결과 배열은 [“Hello”, “”, “”, “World”] 처럼 생성된다. 왜냐면 Hello와 World 사이에 공백이 연속하여 두 개 들어갔기 때문이다. 공백을 빈 문자열 처리한다는 게 아무리 봐도 이해는 안되지만 이해안될 땐 외우는 수 밖에……………..
아무튼, 위의 문제에서는 removeEmptyStrings()메서드를 따로 빼서 배열을 파라미터로 전달받으면 공백이 아닌 배열 값의 개수(count)를 세고, 공백이 아닌 개수만큼의 크기의 배열을 만들어서 공백을 제외한 배열인 result를 만든다. 이 result의 length를 출력해주면 문제 해결!