문제
준하는 사이트에 회원가입을 하다가 joonas라는 아이디가 이미 존재하는 것을 보고 놀랐다. 준하는 놀람을 ??!로 표현한다.
준하가 가입하려고 하는 사이트에 이미 존재하는 아이디가 주어졌을 때, 놀람을 표현하는 프로그램을 작성하시오.
입력 조건
첫째 줄에 준하가 가입하려고 하는 사이트에 이미 존재하는 아이디가 주어진다. 아이디는 알파벳 소문자로만 이루어져 있으며, 길이는 50자를 넘지 않는다.
출력 조건
첫째 줄에 준하의 놀람을 출력한다. 놀람은 아이디 뒤에 ??!를 붙여서 나타낸다.
풀이
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("아이디를 입력해주세요:");
String userId = scanner.nextLine();
System.out.println(userId + "??!");
}
}
얼마 전에 배운 scanner.nextLine을 사용하면 입력값을 문자열로 저장이 되서 쉽게 성공한줄 알았다.
꿀인줄 알았다.
오늘도 입력 조건을 확인하지 않아서 생긴 문제였다.
예외처리? 는 아니고 조건을 걸어줘야했다.
가위 바위 보 만들기 썼던 방식과 동일하게 해주면 될거 같은데 영어 대소문자에 글자수 제한을 하는 법을 모른다...
외우지는 못하고 그때 그때 붙여다 써야겠다...
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("아이디를 입력해주세요:");
String userId = scanner.nextLine();
while (!isValidId(userId)) {
System.out.println("아이디는 알파벳 소문자로만 이루어져 있어야 하며, 길이는 50자를 넘지 않아야 합니다.");
userId = scanner.nextLine();
}
System.out.println(userId + "??!");
}
private static boolean isValidId(String id) {
if (id.length() > 50) {
return false;
}
String regex = "^[a-zA-Z]*$";
if (id.matches(regex)) {
return true;
} else {
return false;
}
}
}
왜지...? 진짜 몰라서 한참 헤매다
소문자만인데 너무 안일했다.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("아이디를 입력해주세요:");
String userId = scanner.nextLine();
while (!isValidId(userId)) {
System.out.println("아이디는 알파벳 소문자로만 이루어져 있어야 하며, 길이는 50자를 넘지 않아야 합니다.");
userId = scanner.nextLine();
}
System.out.println(userId + "??!");
}
private static boolean isValidId(String id) {
if (id.length() >= 50) {
return false;
}
String regex = "^[a-z]*$";
if (id.matches(regex)) {
return true;
} else {
return false;
}
}
}
regex 부분에서 대문자 영역만 지웠더니 해결이 됐다.
진짜 왜 그러세요...
백준과 같은 온라인 코딩 테스트 환경에서는 사용자의 입력이 미리 정해져 있습니다. 따라서 Scanner를 사용하여 실시간으로 입력을 받는 것이 아니라, 미리 주어진 입력값을 처리하는 로직이 필요합니다.
따라서, 사용자로부터 실시간 입력을 받아 처리하는 로직(while(!isValidId(userId)))은 백준 같은 테스트 환경에 적합하지 않습니다. 이 부분을 제거하고, 입력값이 주어졌을 때 그것이 유효한지를 검사하도록 코드를 수정해야 합니다.
어제는 잘 됐는데 도대체 왜?
도저히 안되서 GPT의 도움을 조금 받았다...(많이 받음)
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String userId = scanner.nextLine();
while (!isValidId(userId)) {
if (!scanner.hasNextLine()) {
return;
}
userId = scanner.nextLine();
}
System.out.println(userId + "??!");
}
private static boolean isValidId(String id) {
return id.length() <= 50 && id.matches("^[a-z]*$");
}
}
System.out.println("아이디를 입력해주세요:"); 이 부분을 삭제했습니다. 백준에서는 사용자에게 입력을 요청하는 프롬프트 메시지를 출력하지 않습니다.
while (!isValidId(userId)) {
if (!scanner.hasNextLine()) {
return;
}
userId = scanner.nextLine();
}
여기에서 문제가 생겼던 것 같다.
scanner.hasNextLine()은 Scanner 객체가 다음 입력을 가지고 있는지 확인하는 메소드입니다. 만약 다음 입력이 없으면
false를 반환하므로, 이 경우 return; 문을 통해 메인 메소드를 종료합니다. 이렇게 하면 NoSuchElementException 을 예방할 수 있습니다.
끝났는데 찜찜하다...
private static boolean isValidId(String id) {
return id.length() <= 50 && id.matches("^[a-z]*$");
}
마지막에 if문을 나처럼 길게 써두면 메모리 제한이 걸린 곳에서는 통과가 안될 수도 있다고 한다...
문자열이 일치하는지 확인 할 경우에 주로 사용된다고 하는데 일치할 경우에는 true를 반환하고, 그렇지 않을 때 false를 반환한다고 한다.
String str = "abc";
boolean result = str.matches("[a-z]*"); // result는 true가 됩니다.
예시인데 "[a-z]*"는 모든 소문자 알파벳으로 이루어진 문자열을 나타내는 정규 표현식이라 한다... 이 놈도 오늘 처음봤다.
여튼 match라는 것을 몰랐다면 메모리 제한에 걸릴 수도 있었고, hasNextLine을 검색하지 않았다면 끝까지 런타임 에러를 해결 못했을 것 같다. GPT 가 아니었다면... 영원히 해결 못했을 것 같다. 만신창이가 됐지만 해결됐으니 다행이다.
정리
메모리 제한까지 고려하기엔 나는 아직 이른데 ... 저렇게 줄이는 법도 있구나 했고 아직도 입력시에 저런 설명을 들어도 잘 모르겠다...
intelliJ에서만 잘되면 되는거 아니냐고... 어제까지만 해도 자신감이 좀 있었는데 오늘 여기서 반나절 보내고 자신감이 증발했다😨
시간될때마다 읽고 그렇게 해야겠다... 오늘은 여기까지
'Knowledge > Algorithm' 카테고리의 다른 글
[10699/JAVA] 오늘 날짜 (0) | 2023.12.19 |
---|---|
[18108/JAVA] 1998년생인 내가 태국에서는 2541년생?! (0) | 2023.12.18 |
[11382/JAVA] 꼬마 정민 (0) | 2023.12.16 |
[10430/JAVA] 나머지 (0) | 2023.12.15 |
[1008/JAVA] A/B (0) | 2023.12.13 |
쓰임 있는 사람이 되기 위해 노력 중입니다.