Java案例怎么实现抽奖算法?

wen java案例 10

本文目录导读:

Java案例怎么实现抽奖算法?

  1. 基础随机抽奖(简单抽奖)
  2. 权重抽奖算法
  3. 完整抽奖系统示例
  4. 使用示例
  5. 进阶:公平洗牌算法

我来介绍几种常见的Java抽奖算法实现方案。

基础随机抽奖(简单抽奖)

实现方式一:简单随机

import java.util.*;
public class SimpleLottery {
    private List<String> participants;
    private Random random;
    public SimpleLottery(List<String> participants) {
        this.participants = new ArrayList<>(participants);
        this.random = new Random();
    }
    // 单次抽奖
    public String draw() {
        if (participants.isEmpty()) {
            return "没有参与者";
        }
        int index = random.nextInt(participants.size());
        return participants.get(index);
    }
    // 抽取多个获奖者(不重复)
    public List<String> drawMultiple(int count) {
        List<String> winners = new ArrayList<>();
        List<String> tempList = new ArrayList<>(participants);
        for (int i = 0; i < count && !tempList.isEmpty(); i++) {
            int index = random.nextInt(tempList.size());
            winners.add(tempList.remove(index));
        }
        return winners;
    }
}

权重抽奖算法

实现方式二:加权随机

public class WeightedLottery {
    private List<Prize> prizes;
    private double totalWeight;
    private Random random;
    public WeightedLottery(List<Prize> prizes) {
        this.prizes = prizes;
        this.random = new Random();
        this.totalWeight = prizes.stream()
            .mapToDouble(Prize::getWeight)
            .sum();
    }
    // 根据权重抽奖
    public Prize draw() {
        double currentWeight = random.nextDouble() * totalWeight;
        double cumulativeWeight = 0;
        for (Prize prize : prizes) {
            cumulativeWeight += prize.getWeight();
            if (currentWeight <= cumulativeWeight) {
                return prize;
            }
        }
        return prizes.get(prizes.size() - 1);
    }
    // 奖品类
    public static class Prize {
        private String name;
        private double weight;  // 权重值
        public Prize(String name, double weight) {
            this.name = name;
            this.weight = weight;
        }
        public String getName() { return name; }
        public double getWeight() { return weight; }
    }
}

完整抽奖系统示例

import java.util.*;
import java.util.stream.Collectors;
public class LotterySystem {
    private List<Participant> participants;
    private List<Prize> prizes;
    private Random random;
    private Map<String, Integer> prizeCount; // 奖品库存
    public LotterySystem() {
        this.participants = new ArrayList<>();
        this.prizes = new ArrayList<>();
        this.random = new Random();
        this.prizeCount = new HashMap<>();
    }
    // 添加参与者
    public void addParticipant(String name, double weight) {
        participants.add(new Participant(name, weight));
    }
    // 添加奖品
    public void addPrize(String name, int quantity) {
        prizes.add(new Prize(name, quantity));
        prizeCount.put(name, quantity);
    }
    // 执行抽奖
    public LotteryResult draw() {
        if (participants.isEmpty() || prizes.isEmpty()) {
            return new LotteryResult(null, null, "参与者或奖品不足");
        }
        // 检查剩余奖品
        List<Prize> availablePrizes = prizes.stream()
            .filter(p -> p.getRemaining() > 0)
            .collect(Collectors.toList());
        if (availablePrizes.isEmpty()) {
            return new LotteryResult(null, null, "奖品已抽完");
        }
        // 选择获奖者(权重算法)
        Participant winner = selectWinner();
        // 选择奖品(简单随机)
        Prize prize = selectPrize(availablePrizes);
        // 更新奖品库存
        prize.decrementRemaining();
        return new LotteryResult(winner, prize, "恭喜中奖");
    }
    // 权重选择获奖者
    private Participant selectWinner() {
        double totalWeight = participants.stream()
            .mapToDouble(Participant::getWeight)
            .sum();
        double targetWeight = random.nextDouble() * totalWeight;
        double cumulativeWeight = 0;
        for (Participant p : participants) {
            cumulativeWeight += p.getWeight();
            if (targetWeight <= cumulativeWeight) {
                return p;
            }
        }
        return participants.get(participants.size() - 1);
    }
    // 随机选择奖品
    private Prize selectPrize(List<Prize> availablePrizes) {
        int index = random.nextInt(availablePrizes.size());
        return availablePrizes.get(index);
    }
    // 内部类
    public static class Participant {
        private String name;
        private double weight;
        public Participant(String name, double weight) {
            this.name = name;
            this.weight = weight;
        }
        public String getName() { return name; }
        public double getWeight() { return weight; }
    }
    public static class Prize {
        private String name;
        private int total;
        private int remaining;
        public Prize(String name, int total) {
            this.name = name;
            this.total = total;
            this.remaining = total;
        }
        public String getName() { return name; }
        public int getRemaining() { return remaining; }
        public void decrementRemaining() { this.remaining--; }
    }
    public static class LotteryResult {
        private Participant winner;
        private Prize prize;
        private String message;
        public LotteryResult(Participant winner, Prize prize, String message) {
            this.winner = winner;
            this.prize = prize;
            this.message = message;
        }
        @Override
        public String toString() {
            if (winner == null || prize == null) {
                return "抽奖结果: " + message;
            }
            return String.format("恭喜 %s 获得 %s!", 
                winner.getName(), prize.getName());
        }
    }
}

使用示例

public class LotteryDemo {
    public static void main(String[] args) {
        LotterySystem system = new LotterySystem();
        // 添加参与者
        system.addParticipant("张三", 1.0);
        system.addParticipant("李四", 2.0);  // 权重更高
        system.addParticipant("王五", 1.0);
        // 添加奖品
        system.addPrize("一等奖", 1);
        system.addPrize("二等奖", 2);
        system.addPrize("三等奖", 3);
        // 执行多次抽奖
        for (int i = 0; i < 5; i++) {
            LotterySystem.LotteryResult result = system.draw();
            System.out.println(result);
        }
    }
}

进阶:公平洗牌算法

public class FisherYatesShuffle {
    // Fisher-Yates洗牌算法,确保公平性
    public static <T> void shuffle(List<T> list) {
        Random random = new Random();
        for (int i = list.size() - 1; i > 0; i--) {
            int j = random.nextInt(i + 1);
            // 交换元素
            T temp = list.get(i);
            list.set(i, list.get(j));
            list.set(j, temp);
        }
    }
    // 使用洗牌算法抽奖
    public static <T> List<T> drawWinners(List<T> participants, int count) {
        List<T> shuffled = new ArrayList<>(participants);
        shuffle(shuffled);
        return shuffled.subList(0, Math.min(count, shuffled.size()));
    }
}
  1. 简单随机:适用于所有参与者概率相同的情况
  2. 权重算法:适用于不同参与者或奖品有不同中奖概率的场景
  3. 库存管理:确保奖品不会超发
  4. 洗牌算法:提供最公平的随机分布
  5. 线程安全:多线程环境需考虑同步

选择哪种算法取决于你的具体需求:是否需要权重、是否需要库存管理、并发访问要求等。

抱歉,评论功能暂时关闭!