Skip to content

Latest commit

 

History

History
104 lines (87 loc) · 2.68 KB

8_其他.md

File metadata and controls

104 lines (87 loc) · 2.68 KB

其他

1、洗牌算法

基本思想是:每次从一组数中随机选出一个数,然后与最后一个数交换位置,并且不再考虑最后一个数。

public class Shuffle {

    public void shuffle(int[] nums){
        Random random=new Random();
        for(int i=nums.length-1;i>=0;i--){
            //[0,i] 之中随机选择一个数
            int j=random.nextInt(i+1); // j 为[0,i] 中随机的下标
            swap(nums,i,j); // i 始终指向 [0,i] 的最后位置
        }
    }

    public void swap(int[] nums,int i,int j) {
        int tmp=nums[i];
        nums[i]=nums[j];
        nums[j]=tmp;
    }

    @Test
    public void test(){
        int[] nums={1,2,3,4,5,6,7,8,9,10};
        for(int i=0;i<nums.length;i++){
            System.out.print(nums[i]+" ");
        }
        System.out.println();
        shuffle(nums);
        for(int i=0;i<nums.length;i++){
            System.out.print(nums[i]+" ");
        }
        System.out.println();
    }
}
1 2 3 4 5 6 7 8 9 10 
7 3 8 5 10 2 1 6 4 9

2、抢红包算法

线段切割法:在一条线段上找 (N-1) 个随机点,就可以将该线段随机且公平地切割成 N 段。算上首端点和尾端点的话,总共有 (N+1) 个点

public class RedPacket {
    /**
     * @param n 抢红包人数
     * @param money 派发红包的金额
     *              如果是小数的话先转化为整数,相应的结果除以 100 即可
     * @return List 存储 n 个红包的金额
     */
    public List<Double> generatePocketByLineCutting(int n, double money){
        Random random=new Random();

        //如果是小数的话先转化为整数
        int newMoney=(int)money*100;

        // 将在长度为 money 线段上随机找出 n-1 个点
        List<Integer> points=new ArrayList<>();
        while (points.size()<n-1){
            int point=random.nextInt(newMoney);
            points.add(point);
        }
        // 加上首尾端点,points 总共保存 n+1 个点
        points.add(0);
        points.add(newMoney);
        Collections.sort(points);
        // 获取这 N 段线段长度
        List<Double> res=new ArrayList<>();
        for(int i=1;i<n+1;i++){
            double len=(points.get(i)-points.get(i-1))*1.0/100;
            res.add(len);
        }
        return res;
    }

    @Test
    public void test(){
        int n=10;
        int money=100;
        List<Double> res=generatePocketByLineCutting(n,money);
        System.out.println(res);
        double sum=0.0;
        for(double d:res){
            sum+=d;
        }
        System.out.println(sum);
    }
}
[21.53, 10.59, 7.63, 24.2, 1.5, 3.7, 0.03, 18.49, 10.38, 1.95]
100.0