各種場景下的演算法,包括洗牌、帶權重的隨即選擇、搶紅包
阿新 • • 發佈:2018-12-22
1、洗牌
private static void swap(int[] arr, int i, int j){ int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } public static void shuffle(int[] arr){ Random rnd = new Random(); for(int i=arr.length; i>1; i--) { swap(arr, i-1, rnd.nextInt(i)); } } //主方法 main(){ int[] arr = new int[13]; for(int i=0; i<arr.length; i++){ arr[i] = i; } shuffle(arr); System.out.println(Arrays.toString(arr)); }
2、帶權重的隨即選擇
業務場景:1元、5元和10元,權重分別為70、20、10
class Pair { Object item; int weight; public Pair(Object item, int weight){ this.item = item; this.weight = weight; } public Object getItem() { return item; } public int getWeight() { return weight; } } public class WeightRandom { private Pair[] options; private double[] cumulativeProbabilities; private Random rnd; public WeightRandom(Pair[] options){ this.options = options; this.rnd = new Random(); prepare(); } private void prepare(){ int weights = 0; for(Pair pair : options){ weights += pair.getWeight(); } cumulativeProbabilities = new double[options.length]; int sum = 0; for(int i = 0; i<options.length; i++) { sum += options[i].getWeight(); cumulativeProbabilities[i] = sum / (double)weights; } } public Object nextItem(){ double randomValue = rnd.nextDouble(); int index = Arrays.binarySearch(cumulativeProbabilities, randomValue); if(index < 0) { index = -index-1; } return options[index].getItem(); } } //主方法 main(){ Pair[] options = new Pair[]{ new Pair("1元",7), new Pair("2元", 2), new Pair("10元", 1) }; WeightRandom rnd = new WeightRandom(options); for(int i=0; i<10; i++){ System.out.print(rnd.nextItem()+" "); } }
3、搶紅包演算法
public class RandomRedPacket { private int leftMoney; private int leftNum; private Random rnd; public RandomRedPacket(int total, int num){ this.leftMoney = total; this.leftNum = num; this.rnd = new Random(); } public synchronized int nextMoney(){ if(this.leftNum<=0){ throw new IllegalStateException("???"); } if(this.leftNum==1){ return this.leftMoney; } double max = this.leftMoney/this.leftNum*2d; int money = (int)(rnd.nextDouble()*max); money = Math.max(1, money); this.leftMoney -= money; this.leftNum --; return money; } } //主方法 main(){ RandomRedPacket redPacket = new RandomRedPacket(1000, 10); for(int i=0; i<10; i++){ System.out.print(redPacket.nextMoney()+" "); } }
整理自《JAVA程式設計的邏輯》