固定总金额、还款天数、还款次数,计算每日每次的还款金额,并且每日的还款次数和每日每次还款金额要在固定范围内取值;工作中要实现这样一个功能,本人将代码贴出来,供大家学习使用,若有问题欢迎指正。
/**
* 固定总金额、还款天数、还款次数,计算每日每次的还款金额
* @author songzl
*
*/
public class RandomEverydayTimesMoney {
public static void main(String[] args) {
RandomEverydayTimesMoney rr = new RandomEverydayTimesMoney();
List<Integer> everydayTimesList = rr.mathDayTimes(40, 1, 40, 70);
rr.mathEverydayTimesMoney(everydayTimesList, 70, 50000, 1000, 10);
}
/**
* 计算每天的还款次数
* @param maxCountDay 每日最大还款次数
* @param minCountDay 每日最小还款次数
* @param totalDays 还款总天数
* @param totalCounts 还款总次数
*/
public List<Integer> mathDayTimes(int maxCountDay,int minCountDay,int totalDays,int totalCounts){
List<Integer> everydayTimesList = new ArrayList<>();
//每日还款最大次数、还款总天数、总次数必须大于0,每日还款最小次数徐大于等于0
if(maxCountDay <= 0 && minCountDay < 0 && totalDays <= 0 && totalCounts <= 0){
throw new RuntimeException("参数输入违反实际业务!");
}
if(totalCounts < totalDays * minCountDay || totalCounts > totalDays * maxCountDay){
throw new RuntimeException("总还款次数必须大于每日最小还款次数与总天数的积并且小于每日最大还款次数总天数的积!");
}
//存放每日的还款次数
int sumTimes = 0;//累加还款次数
for(int i = 1; i <= totalDays; i++){
if(i == totalDays){//最后一天还款次数
everydayTimesList.add(totalCounts - sumTimes);
System.out.println(i + "天=" + (totalCounts - sumTimes) + "笔");
}else{
int everydayTimes = getRandomEveryDayTimes(totalCounts, sumTimes, maxCountDay,minCountDay, totalDays, i);
if(everydayTimes != 0){
everydayTimesList.add(everydayTimes);
sumTimes += everydayTimes;
System.out.println(i + "天=" + everydayTimes + "笔");
}else{
i = i - 1;
}
}
}
return everydayTimesList;
}
/**
* 计算当前天的还款次数
* @param totalCounts 总还款次数
* @param sumTimes 累计已还款的次数
* @param maxCountDay 每日最大还款次数
* @param minCountDay 每日最小还款次数
* @param totalDays 还款天数
* @param nowday 当前天数
* @return
*/
public int getRandomEveryDayTimes(int totalCounts, int sumTimes, int maxCountDay,
int minCountDay, int totalDays, int nowday) {
int param = this.getRandomValue(maxCountDay, minCountDay);
sumTimes += param;//累加还款次数
int num = totalCounts - sumTimes;//还剩余的还款次数
int maxNum = maxCountDay * (totalDays - nowday);//剩余的最大次数
int minNum = minCountDay * (totalDays - nowday);//剩余的最小次数
if(totalCounts > maxCountDay * totalDays){
throw new RuntimeException("还款总次数设置不能大于日最大还款次数与天数的积!");
}
if (num <= maxNum && num > minNum ) {
return param;
} else {
return 0;
}
}
/**
* 得到一个范围内的随机数
* @param max 最大值
* @param min 最小值
* @return
*/
public int getRandomValue(int max, int min) {
if(max < min){
throw new RuntimeException("最小值不能大于最大值!");
}
Random random = new Random();
int s = random.nextInt(max) % (max - min + 1) + min;
return s;
}
/**
* 计算每日每天次还款金额
* @param list 存放每日还款次数
* @param totalCounts 还款总次数
* @param totalMoney 还款总金额
* @param maxMoneyDay 每日还款最大金额
* @param minMoneyDay 每日还款最小金额
*/
public void mathEverydayTimesMoney(List<Integer> list,int totalCounts,float totalMoney,int maxMoneyDay,int minMoneyDay){
if(totalMoney < totalCounts * minMoneyDay || totalCounts > totalCounts * maxMoneyDay){
throw new RuntimeException("总还款金额必须大于每日最小还款金额与总次数的积并且小于每日最大还款金额与总次数的积!");
}
int sumcount = 0;// 累计算出的笔数
float summoney = 0F;// 累计算出的金额
for(int i=0;i<list.size();i++){
for(int j=1;j<list.get(i);j++){
if (totalCounts > sumcount + 1) {
int lastMaxMoneyDay = (int) ((totalMoney * 100 - summoney * 100) / (totalCounts - sumcount));
lastMaxMoneyDay = lastMaxMoneyDay / 100;
int param = randomMoney(totalMoney, maxMoneyDay,minMoneyDay, lastMaxMoneyDay, totalCounts,sumcount, summoney);
if (param != 0) {
System.out.println((i + 1) + "天 第" + j + "笔=" + param + "元");
// 插入数据库
sumcount += 1;
summoney += param;
} else {
j = j - 1;
}
}
}
if (totalCounts - sumcount == 1) {
System.out.println((i + 1) + "天 第" + list.get(i) + "笔=" + (totalMoney - summoney) + "元");
// 插入数据库
}
}
}
/**
* 计算每次的还款金额
* @param money 总金额
* @param Max_money_day 日还款最大金额设置
* @param Min_money_day 日还款最小金额设置
* @param last_Max_money_day 计算下一个日还款最大金额
* @param counts 还款总次数
* @param sumcount 累计还款次数
* @param summoney 累计金额
* @return
*/
public int randomMoney(float totalMoney, int maxMoneyDay, int minMoneyDay,
int lastMaxMoneyDay, int totalCounts, int sumcount, float summoney) {// 随机金额
int param = 0;
DecimalFormat df = new DecimalFormat("###.##");
if (totalCounts / 2 >= sumcount + 1) {
param = getRandomValue(maxMoneyDay, minMoneyDay);
} else {
param = getRandomValue(lastMaxMoneyDay, minMoneyDay);
}
summoney += param;
float num = totalMoney * 100 - summoney * 100;//剩余还款额度
num = num / 100;
num = Float.parseFloat(df.format(num));
float minNum = (totalCounts - (sumcount + 1)) * minMoneyDay;
minNum = Float.parseFloat(df.format(minNum));
float maxNum = (totalCounts - (sumcount + 1)) * maxMoneyDay;
maxNum = Float.parseFloat(df.format(maxNum));
if(totalMoney > maxMoneyDay * totalCounts){
throw new RuntimeException("总还款额度设置不能大于最大还款金额和总次数的积!");
}
if (num > minNum && num < maxNum) {
return param;
} else {
return 0;
}
}
}