Lotto 번호생성 (Set 사용 없이 중복제거) - 0단계

이동명·2023년 5월 30일
0
post-thumbnail

# 1~46 까지의 난수를 생성하고 6개의 번호를 추출한다. 그리고 로또 번호를 6번 뽑는다. 다만 중복이 제거 되어야 하며 Set 자료구조 사용을 금지한다.

동료들과 함께 풀어본 문제이고 각자의 접근이 다 다르기 때문에 여러가지 입장을 한번 살펴보자

나의풀이

import java.util.*;

public class LottoMy {
    static int[] arr = new int[6];

    public static void main(String[] args) {
        setNum(0);
        System.out.println(Arrays.toString(arr));
    }

    public static void setNum(int i) {
        // 횟수 제한..
        if (i > 5) {
            return;
        }

        // 난수 생성
        int num = (int) (Math.random() * 45 + 1);

        boolean isExist = false;

        // 중복 체크
        for (int j = 0; j < 6; j++) {
            if (num == arr[i]) {
                isExist = true;
                break;
            }
        }

        if (!isExist) {
            arr[i] = num;
        }

        setNum(isExist ? i : i + 1);
    }
}

동료 A의 풀이

import java.util.ArrayList;
import java.util.List;

public class Lotto {
    public static void main(String[] args) {
        System.out.println(addLottoNumber(new ArrayList<>()));
    }
    static List<Integer> addLottoNumber(List<Integer> lotto){
        if(lotto.size()==6){
            return lotto;
        }
        while(true){
            int number = (int)(Math.random() * 45)+1;
            if(!lotto.contains(number)){
                lotto.add(number);
                break;
            }
        }
        return addLottoNumber(lotto);
    }
}

재귀에 List를 넣어주고 횟수제한을 제한한 뒤 List에 난수에가 포함이 되어 있지 않다면 List에 추가하는식으로 중복을 제거 하는 방법이다.
가장 일반적이고 간편한 방법인 것 같다.

동료 B의 풀이

import java.util.ArrayList;
import java.util.List;

public class Lotto {
    static boolean[] visited = new boolean[46];
    static List<Integer> list = new ArrayList<>();
    
    //재귀함수를 사용해서
    public static void main(String[] args) {
        for(int i=0;i<5;i++){
            System.out.println(i+"번째 로또 출력");
            getSixNumber();
            System.out.println(list.toString());
            list.clear();
        }
    }
    static void getSixNumber(){
        if(list.size()==6){
            return;
        }
        int idx =(int)(Math.random()*45)+1;
        if(!visited[idx]){
            visited[idx]=true;
            list.add(idx);
        }
        getSixNumber();
    }
}

boolean 46개의 배열을 만들어 카드 뒤집기같은 느낌으로 중복을 제거하는 방법이다. 시간복잡도 측면에선 이방법이 가장 빠르다고 한다. 알고리즘이 어느정도 익숙한 동료의 풀이이다.

동료 C의 풀이

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class Lotto {
    public static List<Integer> LottoNumbers = new ArrayList<>();
    public static void main(String[] args) {
        while (LottoNumbers.size() < 6) {
            LottoNumbers.add(getLottoNumber());
        }
        System.out.println(LottoNumbers);
    }
    public static int getLottoNumber() {
        int number = (int) (Math.random() * 45 + 1);
        if (!checknumber(number))
            number = getLottoNumber();
        return number;
    }
    public static boolean checknumber(int number) {
        for (int i = 0; i < LottoNumbers.size(); ++i) {
            if (LottoNumbers.get(i) == number)
                return false;
        }
        return true;
    }
}

행위 별로 메소드를 나눠놓은 동료의 풀이이다. 각자의 책임에 따라 메소드를 분리하는 행위는 좋은 행위 인 것 같다.

동료 D의 풀이

import java.util.HashSet;
import java.util.*;

public class Lotto {
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            Map<Integer, Integer> dict = new HashMap<>();
            getnum(dict);
            System.out.println(dict.keySet());
        }
    }
    public static Map<Integer, Integer> getnum(Map<Integer, Integer> dict) {
        if (dict.size() == 6) return dict;
        int num = (int) (Math.random() * 45 + 1);
        if (!dict.containsKey(num)) {
            dict.put(num, 0);
        }
        return getnum(dict);
    }
}

Map.put 은 덮어쓰는 특성을 사용해 중복을 제거한 방식이다. Set 을 사용하지 못한다면 Map을 사용하는것도 하나의 방법이 될 수 있는 것 같다.

profile
Web Developer

0개의 댓글