简单的随机抽奖算法
题目:写一个随机抽奖的算法,有100个数字,每次抽两次,其中1-到10必须中一个。使用java写一个算法出来。
备注:drawLotteryAdvanced方法更为灵活可以设置抽奖次数,简单的测试可以使用drawLottery方法
import java.util.*;public class LuckyDraw {/*** 随机抽奖算法* 从1-100中抽取2个数字,且必须包含1-10中的至少一个数字* @return 包含两个抽中数字的列表*/public static List<Integer> drawLottery() {Random random = new Random();List<Integer> result = new ArrayList<>();// 确保至少有一个数字来自1-10int firstNumber = random.nextInt(10) + 1; // 1-10之间的随机数result.add(firstNumber);// 第二个数字可以是1-100中的任意数字(包括已抽中的数字)int secondNumber = random.nextInt(100) + 1; // 1-100之间的随机数result.add(secondNumber);// 如果第二个数字和第一个重复,重新抽取第二个数字while (secondNumber == firstNumber) {secondNumber = random.nextInt(100) + 1;result.set(1, secondNumber); // 更新第二个数字}// 随机打乱顺序(可选,让结果看起来更随机)Collections.shuffle(result);return result;}/*** 抽奖算法(优化版)- 避免重复且确保1-10至少一个* @return 包含两个不同数字的列表*/public static List<Integer> drawLotteryOptimized() {Random random = new Random();Set<Integer> resultSet = new HashSet<>();// 确保至少有一个数字来自1-10int guaranteedNumber = random.nextInt(10) + 1;resultSet.add(guaranteedNumber);// 第二个数字可以是1-100中的任意不同数字int secondNumber;do {secondNumber = random.nextInt(100) + 1;} while (resultSet.contains(secondNumber));resultSet.add(secondNumber);return new ArrayList<>(resultSet);}/*** 抽奖算法(通用版)- 可以指定抽奖次数* @param totalNumbers 总数字范围* @param drawCount 抽奖次数* @param guaranteedRange 必须包含的范围* @return 抽中的数字列表*/public static List<Integer> drawLotteryAdvanced(int totalNumbers, int drawCount, int[] guaranteedRange) {if (drawCount <= 0 || totalNumbers <= 0 || guaranteedRange == null || guaranteedRange.length < 2) {throw new IllegalArgumentException("参数错误");}Random random = new Random();Set<Integer> result = new HashSet<>();// 确保至少有一个数字在指定范围内int min = guaranteedRange[0];int max = guaranteedRange[1];int guaranteedNumber = random.nextInt(max - min + 1) + min;result.add(guaranteedNumber);// 抽取剩余的数字while (result.size() < drawCount) {int nextNumber = random.nextInt(totalNumbers) + 1;result.add(nextNumber);}return new ArrayList<>(result);}/*** 测试抽奖算法*/public static void testDraw(int testCount) {System.out.println("测试 " + testCount + " 次抽奖结果:");System.out.println("==================================");Map<Integer, Integer> frequencyMap = new HashMap<>();int validCount = 0;for (int i = 0; i < testCount; i++) {List<Integer> result = drawLotteryOptimized();// 检查是否包含1-10的数字boolean containsRequired = false;for (int num : result) {if (num >= 1 && num <= 10) {containsRequired = true;break;}}if (containsRequired) {validCount++;}// 统计频率for (int num : result) {frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1);}if (i < 10) { // 只显示前10次结果System.out.println("第 " + (i + 1) + " 次: " + result + (containsRequired ? " ✓" : " ✗"));}}System.out.println("==================================");System.out.println("有效抽奖次数: " + validCount + "/" + testCount + " (" + (validCount * 100.0 / testCount) + "%)");System.out.println("1-10数字出现频率统计:");// 输出1-10数字的出现频率for (int i = 1; i <= 10; i++) {int count = frequencyMap.getOrDefault(i, 0);System.out.printf("数字 %2d: %4d 次 (%.2f%%)%n", i, count, count * 100.0 / (testCount * 2));}}public static void main(String[] args) {// 测试基本功能System.out.println("=== 基本抽奖测试 ===");for (int i = 0; i < 5; i++) {List<Integer> result = drawLottery();System.out.println("抽奖结果 " + (i + 1) + ": " + result);}System.out.println("\n=== 优化版抽奖测试 ===");for (int i = 0; i < 5; i++) {List<Integer> result = drawLotteryOptimized();System.out.println("抽奖结果 " + (i + 1) + ": " + result);}System.out.println("\n=== 通用版抽奖测试 ===");for (int i = 0; i < 5; i++) {List<Integer> result = drawLotteryAdvanced(100, 2, new int[]{1, 10});System.out.println("抽奖结果 " + (i + 1) + ": " + result);}// 大规模测试System.out.println("\n=== 大规模测试 ===");testDraw(1000);}
}