[Java] 랜덤 숫자로 로또 번호와 주민등록번호 만들기 (Math.random(), Random.nextInt())

jina·2024년 3월 30일
0

Java

목록 보기
4/10
post-thumbnail
post-custom-banner

❔ 문제

랜덤 숫자를 반환해서 풀 수 있는 두 가지 문제를 정리해 보았습니다.

1번 문제: Math.random()
2번 문제: Random.nextInt(bound)

💭 1번 문제

Math.random()을 사용해서 1부터 45 사이의 숫자 6개를 랜덤으로 출력하는 로또 번호 생성기를 만듭니다.

접근 방법

Math.random()는 0부터 1미만의 double 타입의 값을 랜덤으로 반환하는 메소드입니다. 0부터 시작해 1에 가까운 무한한 실수를 반환하기 때문에 0.399390126516721와 같은 값이 출력됩니다.

// 0 이상 1 미만 값 반환:
Math.random();

문제에서는 1에서 46미만의 수를 구해야 하기 때문에 범위를 조정해 주어야 합니다.

// 0 이상 46 미만 값 반환:
Math.random() * 46;

// 최소값을 조정해서 1 이상 47 미만 값 반환:
Math.random() * 46 + 1;

// 최대값을 조정해서 1 이상 46 미만 값 반환:
Math.random() * 45 + 1;

// 정수를 출력하기 위해 형변환
(int) (Math.random() * 45) + 1;

이렇게 완성된 Math.random() 메소드를 활용해 6개의 값을 구하기 위해 for문을 활용합니다. 해당 6개 값은 중복이 불가하고 순서는 상관이 없습니다. 해당 조건에 맞게 값을 저장하기 위해 HashSet을 사용했고 아래처럼 코드를 작성할 수 있었습니다.

HashSet set = new HashSet();

for (int i = 0; set.size() < 6; i++){ // set.size()의 초기값은 0으로 i와 동일하게 시작된다
	int num = (int) (Math.random() * 45) + 1;
	set.add(num);
}

System.out.println("로또 번호: " + set);

실행하면 아래같은 결과 값이 출력됩니다.

로또 번호: [40, 41, 44, 14, 31, 15]

주요 코드

  • Math.random(): 0부터 1미만의 실수 값을 반환
  • HashSet: 중복을 허용하지 않고 순서를 보장하지 않는 Set 컬렉션

💭 2번 문제

출생한 년도(yyyy), 월(mm), 일(dd) 그리고 성별(m/f)을 주어진 형식에 맞춰 사용자에게 Scanner로 입력받아 주민등록번호를 생성합니다. 주민등록번호는 yymmdd-0000000 (뒷번호 7자리 = m은 3, f는 4 + 랜덤 숫자 6개) 형태로 이루어져야 하고, 랜덤 번호는 Random 클래스를 활용해 생성합니다. yyyy는 2020년도 이후로 입력한다는 전제로 작성합니다.

접근 방법

메인 메소드에는 Scanner로 사용자에게 int와 String 타입으로 값을 입력받습니다.

import java.util.Scanner;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.println("[주민등록번호 계산]");
        System.out.print("출생년도를 입력해 주세요.(yyyy):");
        int year = sc.nextInt();
        sc.nextLine();

        System.out.print("출생월을 입력해 주세요.(mm):");
        int month = sc.nextInt();
        sc.nextLine();

        System.out.print("출생일을 입력해 주세요.(dd):");
        int date = sc.nextInt();
        sc.nextLine();

        System.out.print("성별을 입력해 주세요.(m/f):");
        String gender = sc.nextLine();

        createNumber(year, month, date, gender);
    }

주민번호 생성을 맡을 메소드에서 yymmdd에 형식에 해당하는 int 타입 데이터는 Integer.toString을 사용해 String 타입으로 변환합니다. 주민번호 뒷부분 생성을 위해 성별에 해당하는 String 타입 데이터는 equals로 입력 값이 정확한지 확인 후 정수로 변환했습니다. 이어지는 랜덤 숫자 6자리는 Random 클래스의 nextInt() 메소드를 사용해 생성하고 출력 포맷을 지정했습니다.

마지막으로 사용자가 입력한 값이 형식에 맞지 않는 경우를 고려해 boolean 타입을 사용해 주민번호를 생성하지 않고 메소드를 빠져나가도록 만들었습니다.

import java.util.Random;

public static void createNumber(int year, int month, int date, String gender) {
        String yy;
        String mm;
        String dd;
        int genderNum = 0;
        boolean result = true;

        if (year < 2020) {
            result = false;
        }
        year = year - (year / 100) * 100;
        yy = Integer.toString(year);

        if (month > 12) {
            result = false;
        }
        mm = String.format("%02d", (month));

        if (date > 31) {
            result = false;
        }
        dd = String.format("%02d", (date));

        if ("m".equals(gender)) {
            genderNum = 3;
        } else if ("f".equals(gender)) {
            genderNum = 4;
        } else {
            result = false;
        }

        if (!result) {
            System.out.println("잘못된 입력입니다.");
        } else {
            Random randomNum = new Random();
            int random = randomNum.nextInt(1000000);
            System.out.println(yy + mm + dd + "-" + genderNum + String.format("%6d", random));
        }
    }

Random 클래스의 객채를 생성해 nextInt(bound) 메소드를 사용하면 0 이상 bound 값 미만의 정수가 반환됩니다. 문제에서 요구하는 랜덤 숫자는 6자리이기 때문에 반환 값이 6자리 미만일 경우에도 형식에 맞출 수 있도록 String.format을 사용해 출력했습니다. 결과적으로 0부터 999999의 값이 6자리로 출력됩니다.

더불어 성별 입력을 구분하는 코드를 변수.equals("문자열") 대신 "문자열".equals(변수)로 수정했습니다. 코드가 복잡해질 경우 변수가 가르키는 참조값이 null이 되어 NullPointerException이 발생하는 상황을 예방할 수 있게 습관을 들이면 좋을 것 같습니다.

이렇게 완성한 번호 생성 메소드를 실행하니 아래같은 결과물을 확인할 수 있었습니다.

[주민등록번호 계산]
출생년도를 입력해 주세요.(yyyy):2024
출생월을 입력해 주세요.(mm):01
출생일을 입력해 주세요.(dd):24
성별을 입력해 주세요.(m/f):f
240124-4863357

주요 코드

  • Integer.toString: 주어진 int 타입 데이터를 String 형태로 반환
  • equals: String 타입의 값을 비교할 때 두 객체에 담겨있는 내용을 비교하고, ==는 두 객체가 참조하는 메모리 위치(주소값)를 비교
  • Random 클래스의 nextInt(bound): 0 이상 bound 값 미만의 정수를 랜덤하게 반환

참고
https://holystory-dev.com/96 (Math.random())
https://adjh54.tistory.com/130#google_vignette (Math.random())

https://madplay.github.io/post/java-random (Random)
https://heytech.tistory.com/167 (Random)
https://jamesdreaming.tistory.com/142 (toString)
https://junior-datalist.tistory.com/215 (equals)

profile
오늘의 기록은 내일의 보물
post-custom-banner

0개의 댓글