작성
·
645
·
수정됨
0
안녕하세요 강사님
예시 문제는 합격하는데 다른 4개의 테스트 케이스는 통과하지 못하고 있습니다.
문제는 런타임에러가 뜨는데 왜 뜨는지 정확한 이유를 아무리 보아도 모르겠습니다...
많이 더러운 코드지만 무엇이 문제인지 확인 한번 부탁 드리겠습니다...
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public String solution(String str) {
String answer = "";
String[] arr = new StringBuilder(str).reverse().toString().split(" ");
List<Integer> list = new ArrayList<>();
for (String s : arr) {
int target = Integer.parseInt(s);
if (target != 2 && target % 2 == 0) continue;
if (target == 1) continue;
boolean check = true;
for (int j = 3; j <= Math.sqrt(target); j+=2) {
if (target % j == 0) {
check = false;
break;
}
}
if (check) list.add(target);
}
for (int i =list.size()-1; i >= 0; i--) {
answer += list.get(i) + " ";
}
return answer;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int input1 = in.nextInt();
in.nextLine();
String str = in.nextLine();
Main main = new Main();
System.out.println(main.solution(str));
return;
}
}
저와 비슷한 사례를 겪는 분들을 질문창에서 발견하고 강사님이 적어두신 2번 케이스의 문제를 복사해서 적어보았는데 통과하였습니다.
저는 split() 메서드를 이용해서 입력받은 문자열을 배열로 변경하는데 이때 문자열 맨 뒤에 공백이 존재하게 되면 런타임 에러가 발생 하는것을 확인했습니다. 아무래도 그부분 때문인것 같은데 맞다면 확인 한번 부탁드리겠습니다.
코드를 수정하였습니다.
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public String solution(String[] arr) {
String answer = "";
for (int i = 0; i < arr.length; i++) {
String s = new StringBuilder(arr[i]).reverse().toString();
int target = Integer.parseInt(s);
if (target != 2 && target % 2 == 0) continue;
if (target == 1) continue;
boolean check = isPrime(target);
if (check) answer += target + " ";
}
return answer;
}
private boolean isPrime(int target) {
for (int j = 3; j <= Math.sqrt(target); j+=2) {
if (target % j == 0) {
return false;
}
}
return true;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int input1 = in.nextInt();
String[] arr = new String[input1];
for (int i = 0; i < input1; i++) {
arr[i] = in.next();
}
Main main = new Main();
System.out.println(main.solution(arr));
return;
}
}
이렇게 하니 해결되었습니다.
혹시 실제 코딩테스트 볼때도 split을 사용할때 요청값끝부분에 있는 공백의 존재 가능성도 염두해두고 사용을 해야하나요? 아니면 단순 이 사이트의 실수였을까요?
답변 2
0
저 또한 수강생이지만, 의견을 드리자면,
코테에서 입력값의 맨 뒷값에 공백을 포함시키지 않는다는 제약을 반드시 가하는지는 모르겠습니다.
만일 이것이 고민될 경우, trim을 통해 맨앞 맨 뒤의 공백을 제거해서 사용할 수도 있을것 같습니다.
또한 split은 지정한 구분자를 사용해서 분리를 시키기에, 공백이 포함될 경우 생각했던 길이와 다른 길이의 배열이 생성될 수 있습니다.
예를 들어,
"1(공백)2(공백)3(공백)4(공백)5(공백)" 를 공백을 기준으로 split한다면,
["1", "2", "3", "4", "5"] 로 길이 5개의 배열이 만들어지나,
"(공백)1(공백)2(공백)3(공백)4(공백)5" 를 공백을 기준으로 split한다면,
["", "1", "2", "3", "4", "5"] 로 길이 6개를 가지는 배열이 생성됨을 확인하였습니다.
발생하신 문제 또한,
처음 입력한 값의 맨 뒤에 공백이 포함될 경우,
reverse 과정에서, 맨 뒤의 공백은 맨 앞의 공백을 가지는 문자열로 변환되고,
이 맨앞의 공백에 의해, 생각했던 길이의 배열보다 1이 더 큰 배열이 생성되기 때문이 아닐까 합니다. (0번째 인덱스 값 : "")
"" 와 같은 빈 문자열은, Integer.parse() 실행시 런타임 에러가 발생합니다. 해당 빈 문자열은 정수형 변환할 수 없기 때문입니다.
아마도 발생하신 예외 또한, NumberFormatException이 발생하시지 않았나 싶습니다.
0
저도 코딩테스트를 본적은 없지만 아마 마지막 입력값에 공백이 있을 것 같지는 않네요
코드에서 오류가 발생한 부분은 테스트 케이스의 입력값을 복사하여 맨뒤에 공백을 제거하여 입력하면 정상적으로 출력되는 것으로 보아 추측하신대로 입력값 끝에 공백 때문에 reverse().split(" ")에서 문제가 생긴 것 같네요
String[] inArr = bf.readLine().split(" ");
입력을 for문으로 하나하나 읽지 않고 라인으로 받은 다음 split을 으로
한번에 입력 할 수 있습니다.
NumberFormatException 맞습니다! 좋은 답변 감사합니다. split을 조심히 사용해야 겠습니다.