您现在的位置是:首页 >技术杂谈 >梯度收费算法网站首页技术杂谈
梯度收费算法
简介梯度收费算法
交电费按梯度收费,总用电
小于等于5度电,每度30元;
大于5度小于等于20度的,每度15元;
大于20度小于等于50度的,每度10元。
大于50度小于等于100度,每度9元;
大于100度小于等于500度,每度8元;
大于500度小于等于1000度,每度7元;
大于1000度小于等于2000度,每度6元;
大于2000度小于等于3000度,每度5元;
大于3000度小于等于4000度,每度4元;
大于4000度小于等于5000度,每度3元;
大于5000度小于等于6000度,每度2元;
大于 6000度 ,每度1元。
例如,某月总用电量为6度,则电费为5*30+1*15 = 165元。
算法实现:
根据题目把交费电量分为12个区间,用两个数组分别存储每个区间的度数及价格,算出每个区间应交费多少,每个区间的交费加起来即可。
例如第一个区间是5度,第二个区间是6度至20度,说明第二个区间的度数为15度。先看总电量是否大于第一个区间的度数5度,如果大于,则5度在第一个区间,按照第一个区间缴费,总电量减5,剩下的电量又看是否大于第二个区间的度数....
下面写了两个方法,第1个是递归方法,代码简单,也好理解,用到了两个额外数组;第2个非递归,代码多一点,用到了一个额外数组。
public class DegreesTest {
// 区间度数数组
public static double[] sectionDegrees = new double[]{5, 15, 30, 50, 400, 500, 1000, 1000, 1000, 1000, 1000, 0};
// 区间价格数组
public static double[] sectionPrices = new double[]{30, 15, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
public static void main(String[] args) {
//方法1
System.out.println(compute2(6, 0)); //165
//方法2
System.out.println(compute(6)); //165
}
/**
* 计算电费方法1 - 递归 - 需要用到 “区间度数数组 sectionDegrees”及 “区间价格数组 sectionPrices”
*
* @param degree 剩余用电度数
* @param i 区间下标
* @return 总电费
*/
public static double compute2(double degree, int i) {
// 度数为0,直接返回
if (degree == 0) {
return 0;
}
// 剩余度数比当前区间度数大
if (degree > sectionDegrees[i]) {
if (sectionDegrees[i] == 0) { //如果是最后一个区间,则总电费=剩余电量*单价1
return degree * sectionPrices[i];
}
//总电费=当前区间电费+后面区间电费 - 递归计算
return sectionDegrees[i] * sectionPrices[i] + compute2(degree - sectionDegrees[i], i + 1);
} else { // 剩余度数小于等于当前区间度数
return degree * sectionPrices[i];
}
}
/**
* 计算电费方法2 - 需要用到 “区间度数数组 sectionDegrees”
*
* @param degree 用电度数
* @return 总电费
*/
public static double compute(double degree) {
// 计算每个区间的度数
for (int i = 0; i < sectionDegrees.length; i++) {
// 剩余度数为0,将当前的区间度数清空
if (degree == 0) {
sectionDegrees[i] = 0;
continue;
}
// 最后一个区间,直接设置剩余的度数
if (i == sectionDegrees.length - 1) {
sectionDegrees[i] = degree;
continue;
}
// 大于区间度数,减去当前区间度数,计算剩余度数
if (degree > sectionDegrees[i]) {
degree -= sectionDegrees[i];
}
// 小于区间度数,将当前区间度数设置为剩余度数
else {
sectionDegrees[i] = degree;
degree = 0;
}
}
// 总电费 = 每个区间电费之和
double result = 30 * sectionDegrees[0] + 15 * sectionDegrees[1] + 10 * sectionDegrees[2]
+ 9 * sectionDegrees[3] + 8 * sectionDegrees[4] + 7 * sectionDegrees[5] + 6 * sectionDegrees[6]
+ 5 * sectionDegrees[7] + 4 * sectionDegrees[8] + 3 * sectionDegrees[9] + 2 * sectionDegrees[10]
+ sectionDegrees[11];
return result;
}
}
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。