看了隔壁的訪問量和點贊量酸了,我也水個博客,估計也沒人看,
問題分析
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;
}
}
隔壁鏈接
可能還有細節沒有完善,歡迎各位大佬多多指正,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/231506.html
標籤:其他
下一篇:自制云游戲服務器!月光Moonlight使用教程,使用串流技術將電腦游戲搬運到手機上游玩!(帶外網無卡頓串流技術) (o?▽?)o 尋覓
