一.问题:
写一个算法,实现随机发红包。确保抢红包的人每个人都能抢到红包,至少0.01元(1分钱)。
二.思路:
(1)要用到radom类方法
(2)至少要有抢红包的人数,红包总金额,红包剩余金额,这几个变量。
(3)为了便于以后修改抢红包算法,将程序分成三个类-----主类,红包类,实现抢红包的类
(4)有一个小问题,随机的,任何数字都有可能,怎么保证每个人都能抢到钱呢?
下面的代码解决了这个小问题
1.当设置抢红包金额不合理时:
if(integerRemainMoney<remainPeople*(int)(minMoney*100)) {
System.out.println("至少红包金额为:"+remainPeople*(int)(minMoney*100));
Scanner scanner=new Scanner(System.in);
System.out.println("请输入红包金额:");
this.remainMoney=scanner.nextDouble();
}
2.当抢的过程中红包不够分时
if(randomMoney<(int)(minMoney*100)) {
randomMoney=(int)(minMoney*100);//确保每个人抢的钱>1分钱
}
int leftortherPeopleMoney=integerRemainMoney-randomMoney;//剩给其他人的钱
int leftortherPeopleNeedMoney=(remainPeople-1)*(int)(minMoney*100);//其他人至少需要的钱
if(leftortherPeopleMoney<leftortherPeopleNeedMoney) {//如果剩下的钱不过分,那么就是前一个人抢多了,将抢多的钱减去,赋给这个人,就能保证后面的人有钱抢。
randomMoney-=leftortherPeopleNeedMoney-leftortherPeopleMoney;
}
三.关键点
(1)Random random.nextInt(随机数取值范围);
(2)元转换成分,便于计算。
(3)remainPepole--抢红包的人数,每抢一个红包人数减去1
randomMoney--用户抢到的钱
remainMoney--红包当前金额
giveMoney---抢红包算法
integerRemainMoney--以分为单位的红包金额
四.代码
1.主类:
public class 抢红包 {
public static void main(String args[]) {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入红包金额:");
double x=scanner.nextDouble();
System.out.println("请输入抢红包人数:");
int y=scanner.nextInt();
RedEnvelope redEnvelope=new RandomRedEnvelope(x,y);
System.out.printf("用下列循环输出%d人抢%.2f红包:\n",redEnvelope.remainPeople,redEnvelope.remainMoney);
showProcess(redEnvelope);
}
public static void showProcess(RedEnvelope redEnvelope) {
double sum=0;
while(redEnvelope.remainPeople>0) {
double money=redEnvelope.giveMoney();
System.out.printf("%.2f\t", money);
sum+=money;
}
String s=String.format("%.2f", sum);
sum=Double.parseDouble(s);
System.out.printf("\n%.2f元的红包被抢完了", sum);
}
}
2.红包类:
abstract public class RedEnvelope {
public double remainMoney;
public int remainPeople;
public double money;
public abstract double giveMoney();
}
3.实现抢红包类:
import java.util.Random; import java.util.Scanner; public class RandomRedEnvelope extends RedEnvelope { double minMoney; int integerRemainMoney; int randomMoney; Random random; RandomRedEnvelope(double remainMoney,int remainPeople){ random=new Random(); minMoney=0.01; this.remainMoney=remainMoney; this.remainPeople=remainPeople; integerRemainMoney=(int)(remainMoney*100); if(integerRemainMoney<remainPeople*(int)(minMoney*100)) { System.out.println("至少红包金额为:"+remainPeople*(int)(minMoney*100)); Scanner scanner=new Scanner(System.in); System.out.println("请输入红包金额:"); this.remainMoney=scanner.nextDouble(); } } public double giveMoney() { if(remainPeople<=0) { return 0; } if(remainPeople==1) { money=remainMoney; remainPeople--; return money; } randomMoney=random.nextInt(integerRemainMoney); if(randomMoney<(int)(minMoney*100)) { randomMoney=(int)(minMoney*100); } int leftortherPeopleMoney=integerRemainMoney-randomMoney; int leftortherPeopleNeedMoney=(remainPeople-1)*(int)(minMoney*100); if(leftortherPeopleMoney<leftortherPeopleNeedMoney) { randomMoney-=leftortherPeopleNeedMoney-leftortherPeopleMoney; } integerRemainMoney=integerRemainMoney-randomMoney; remainMoney=(double)(integerRemainMoney/100.0); remainPeople--; money=(double)(randomMoney/100.0); return money; } }
以上代码虽然能实现抢红包,但有个小瑕疵。到最后的人抢到的都是0.01,因为前面的人很可能抢多了,后面就不够分了。