JAVA作业——红包分发

看了隔壁的访问量和点赞量酸了。我也水个博客,估计也没人看。
问题分析
1、如何保证金额的随机。
2、保留两位小数后会导致分发的金额与总金额不匹配的问题。
解决方案
1、我们用一个数组来存红包个数个的随机数(ran数组),并且用个变量(sum)累加每个随机数,这样第i个人抢到的红包金额即为 ans[i] = ran[i]*money/sum;
2、我们除的时候会有好多位小数,而我们一般抢红包只有2位小数,所以我们应该只保留两位小数,但是假设有1万个0.001这样的红包每个人抢到的都是0.001,我们只保留两位即我们抢到的金额为0。腾讯含泪血赚10元。(好像也没赚多少。。。),所以我们应该采用如下方案。

 double[] ans  = new double[num];    //用来存取每个人分到的金额。
        double sum2= 0;                     //用来存取每个分到的金额的和
        for(int i=0;i<num;i++)
        {
    
    
            ans[i] = (int)(ran[i]*money/sum * 100);         //ran[i]*money/sum 即这个人应该分到的金额,注意ran[i]/sum 因为sum和ran[i]都是随机数所以可以随机分发红包。
            sum2 += ans[i];                                     //(ran[i]*money/sum * 100);  乘100即将小数点后两位变成了整数,然后转换为int即保留了两位小数。
            ans[i]/=100;
        }
        sum2/=100;                              //将sum2处于一百,即生成小数点后两位
        double temp = money - sum2;             //temp = money - sum2 temp 即因为每份红包只保留2位小数导致与红包总金额的差值
        ans[r.nextInt(num)] += temp;            //将这个差值随机加入一个红包内

然后就可以愉快的敲代码了。
主函数代码:

package ex1;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public class Main {
    
    
    public static void main(String[] args) {
    
    
        double money;
        int num;
        Scanner cin = new Scanner(System.in);

        do{
    
    
            System.out.print("请输入红包总金额:");
            money = cin.nextDouble();
            if(money<0.01) System.out.println("红包总金额不合法,请重新输入。");
        }while(money <0.01);

        do{
    
    
            System.out.print("请输入红包个数:");
            num = cin.nextInt();
            if(num<=0 || num>=10005)  System.out.println("红包个数不合法,请重新输入。");
            if(money/num < 0.01) System.out.println("每个人分到的钱连0.01都不到,请重新输入份数");
        }while(num<=0 ||(money/num < 0.01));

        RedPacket rp0 = new RedPacket(money,num);

        int[] ran = new int[num]; //用来存取随机数
        Random r = new Random();
        int sum = 0,x;  //sum用来记录所有随机数的和,x用来存取随机数。
        for(int i = 0;i<num;i++)
        {
    
    
            x = r.nextInt(100);
            sum += x;
            ran[i] =x;
        }

        double[] ans  = new double[num];    //用来存取每个人分到的金额。
        double sum2= 0;                     //用来存取每个分到的金额的和
        for(int i=0;i<num;i++)
        {
    
    
            ans[i] = (int)(ran[i]*money/sum * 100);         //ran[i]*money/sum 即这个人应该分到的金额,注意ran[i]/sum 因为sum和ran[i]都是随机数所以可以随机分发红包。
            sum2 += ans[i];                                     //(ran[i]*money/sum * 100);  乘100即将小数点后两位变成了整数,然后转换为int即保留了两位小数。
            ans[i]/=100;
        }
        sum2/=100;                              //将sum2处于一百,即生成小数点后两位
        double temp = money - sum2;             //temp = money - sum2 temp 即因为每份红包只保留2位小数导致与红包总金额的差值
        ans[r.nextInt(num)] += temp;            //将这个差值随机加入一个红包内
        double flag = 0;    //检测各个红包金额的和是否可以等于总金额
        for(int i = 0;i<num;i++)
        {
    
    
            flag += ans[i];
            System.out.printf("%.2f\n",ans[i]);
        }
        if(Math.abs(flag-money) < 1e-8){
    
    
            System.out.println("相等");
        }else System.out.println("不相等");
    }
}

红包类代码:

package ex1;

public class RedPacket {
    
    
    private double money;   ///红包金额
    private int num;    //红包个数
    public RedPacket(double money, int num) {
    
    
        this.money = money;
        this.num = num;
    }

    public RedPacket(){
    
    }

    public double getMoney() {
    
    
        return money;
    }

    public int getNum() {
    
    
        return num;
    }

    public void setMoney(double money) {
    
    
        this.money = money;
    }

    public void setNum(int num) {
    
    
        this.num = num;
    }
}

隔壁链接
可能还有细节没有完善,欢迎各位大佬多多指正。

猜你喜欢

转载自blog.csdn.net/weixin_45822897/article/details/110734534