옹실이의 개발이야기

Java

Java 멀티로또 : 명단파일, 숫자 입력받아서 숫자만큼 랜덤 뽑기

옹실 2020. 11. 9. 21:40

Java 로또 심화 버전!
랜덤으로 뽑을 명단 파일, 몇명 뽑을지 숫자 입력받아서 입력받은 수만큼 랜덤 뽑기
명단 파일을 받겠다고 했지만, 사실 파일을 직접 입력할 수 있다는 것을 보여주기 위해 입력받는 것일 뿐
기준은 '우리반리스트.txt'라는 파일로 코딩했다.

* 순서 *
1. 파일 불러오기 : 엔터만 쳤을때 자동으로 우리반리스트 파일이름 넣기
2. 불러온 파일 읽고, 배열에 담기.
3. 리스트에서 몇명 뽑을건지 값 받기
4. 받은 수만큼 랜덤 뽑기 ( 중복방지 : TreeSet 이용(TreeSet 사이즈가 받은 값보다 작으면 다시 반복) )


1. 파일 불러오기 : 엔터만 쳤을때 자동으로 우리반리스트 파일이름 넣기

아무것도 입력 안하고 엔터쳤을 때 : '우리반리스트.txt'라는 파일로 적용되고, 
직접 텍스트를 입력하면 넘어가지 않고, 엔터를 쳐서 넘어가도록 해보았다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.util.*;
import java.io.*;
 
class MultiLotto2_study3 {
    String list = "우리반리스트.txt";
    String line; //한줄씩 읽을 준비
    String student[] = new String[23];
    int count = 0;
 
    void input(){
        BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in)); //System.in으로 파일 입력받기
        System.out.println("'우리반리스트'를 넣어쥬세여!!!");
 
        try{
            String listfile = br1.readLine(); //입력값 listfile에넣는다
            if ( listfile.equals("") ){ //입력값이 엔터일때
                this.list = list; //list는 우리반리스트.txt로 하겟다
                System.out.println(list);
            } else {
                System.out.println("우리반리스트만 넣어쥬세여");
                input();
            }
        }catch(IOException ie){}
    }
    
}
 
cs

System.in으로 직접 파일을 입력받은 후 InputStreamReader와 BufferedReader로 필터링(?)을 하게 했다.
입력받은 값을 listfile에 넣고, 그 값의 내용이 ""일때(엔터일 때)
list를 5번째 코드에서 설정한 "우리반리스트.txt" 로 적용시켰다.

엔터 안치면 input() 메소드를 다시 호출해 재입력받도록 했다.

 

2. 불러온 파일 읽고, 배열에 담기

아무것도 입력 안하고 엔터쳤을 때 : '우리반리스트.txt'라는 파일로 적용되고, 
직접 텍스트를 입력하면 넘어가지 않고, 엔터를 쳐서 넘어가도록 해보았다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    void fileRead(){
        FileReader fr = null;
        BufferedReader br2;
 
        try{
            fr = new FileReader(list);
            br2 = new BufferedReader(fr);
            
            //파일 내용 하나씩 배열에 담기
            String list = null;
            while( (list=br2.readLine()) != null ){
                student[count] = list;
                count++;
            }
        }catch(IOException ie){
        }
    }
cs

FileReader로 파일을 통째로 읽은 후
BufferedReader로 파일을 한 줄씩 읽는다.

한 줄씩 읽은것을 student라는 고정 배열의 0번째 칸부터 하나씩 담는다.
[ ]안에 들어있는 count는 0으로 초기화 한 전역변수로 (위 1. 내용의 8번째 코드)
고정배열에 내용을 하나씩 넣을때마다 count++;로 count의 값을 1씩 증가시켰다.
즉, 고정 배열에 내용을 하나씩 넣을 때마다 배열의 칸을 1씩 이동(?)시켜서 내용을 넣어준 것

 

3. 명단에서 몇명 뽑을건지 값 받기

몇명 뽑을건지 입력받는 것도 역시 System.in을 이용했다.
명단에 현재 23명밖에 없어서 a>22 또는 a<0 로 조건문을 걸어 예외처리를 했다.
(0~22까지 총 23이기 때문에 a>22로 해줬음)

입력값이 숫자가 아닐 경우를 대비해 NumberFormatException을 걸어 숫자만 입력받도록 함

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    int a; //몇명뽑을지 받아서 여기에 넣을거임
    void choose(){
        BufferedReader br3 = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("몇명 뽑기ㄱㄱ? ");
        try{
            String luckyNum = br3.readLine();
            a = Integer.parseInt(luckyNum);
            if(a > 22 || a < 0 ) {
                System.out.println("명단에 22명밖에 엄쪄!!!!");
                choose();
            }
        }catch(IOException ie){
        }catch(NumberFormatException ne){
            System.out.println("숫자만 입력해쥬삼");
            choose();
        }
    }
cs

 

1~3. 실행결과

숫자나 다른걸 입력했을때 다시 입력해달라는 문구가 뜨고, 엔터를 치자 몇명 뽑을지 입력받는 문구가 뜬다.

 

 

4. 입력받은 수만큼 랜덤 뽑기

랜덤 뽑기는 중복수가 생길 수 있기 때문에 TreeSet을 이용해 중복을 방지했다.
TreeSet은 중복이 안되기 때문에 값을 넣을 때 중복되는 값은 들어가지 않는다.
이 점을 이용해 TreeSet의 사이즈가 3번에서 입력받은 값보다 작으면 다시 반복해서 뽑도록 했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    TreeSet<Integer> set = new TreeSet<Integer>();
 
    int amount_num = 23;
    int n;
 
    void selectRan(){
        Random r = new Random();
        for(int i=0; i<a; i++){
            n = r.nextInt(amount_num); //입력받은 수만큼 랜덤 수 뽑아서
            set.add(n); //treeSet에 넣는다
            if( set.size() < a ){ //중복수가 생겨서 a만큼 treeset에 안담기면 다시 뽑긔
                i--;
            }else{
                break;
            }
        }
        for(int i : set){
            System.out.println("당첨번호: "+i+", 당첨자: "+student[i]);
        }
    }
cs

amount_num을 23으로 한 것도 역시
랜덤수를 뽑을 때 0~22까지의 수를 기준으로 해야하기 때문이다.

set에 랜덤수 n을 넣어주고 if문에서 set의 사이즈를 기준으로 중복을 방지했다.

마지막에 set에 들어가있는 것들을 모두 꺼내서
System.out.println으로 당첨번호와 당첨자(student 고정배열에 있는 것 꺼냄)를 표시했다.



5. 메인메소드 호출

지금까지 한 것 메인 메소드 호출로 실행시켜준다.

1
2
3
4
5
6
7
    public static void main(String[] args) {
        MultiLotto2_study3 ms3 = new MultiLotto2_study3();
        ms3.input();
        ms3.fileRead();
        ms3.choose();
        ms3.selectRan();
    }
cs

 

총 실행결과

몇명뽑을지 물어봤을때 명단에 있는 23명보다 큰 수를 입력하면 다시 입력받고, 23명보다 적은 수를 입력하면 당첨번호와 당첨자가 같이 표시된다.