以上是官方的解释,不明觉厉。
我们还是举个栗子吧:
比如:
0-500 度 ==》 收费价格是 0.5元 定额内
500-800度 ==》 收费价格是 0.8元 第一阶梯
800-1000度 ==》 收费价格是 1.2元 第二阶梯
1000度以上 ==》 收费价格是1.5元 第三阶梯
当用户已经用了200度的时候,再购买700 度的时候,需要支付多少钱?
刚开始遇到这个问题的时候,第一反应就是,先判断 在哪个阶梯,然后比较大小,然后就没有然后了,发现,会有很多种情况,这里还只是 三个阶梯,假设有很多
阶梯的情况下,会 go die 的,所以,后来想看看能不能用算法来解决,
思路: 从最高阶梯开始循环, 用(总量(当前值+购买值)-最高阶梯最低值) 与 购买值 进行相减 >0,则 处于最高阶梯的 直接取购买值,<0,则 取 (总量(当前值+购买值)-最高阶梯最低值)
循环到下一个阶梯时, 用 剩余值(购买值-上一阶梯的取值)与 这个阶梯的区域差值进行相减 >0,则 处于这一阶梯的 取值为 区域差值,<0,则 取 剩余值
以此类推
我这里是用java 的语法,话不多说,直接上代码:
public class AreaValueUtil {
public static void main(String[] args) {
double currentMount=200;
double needMount=100;
// double priceArrs[]={0.5d,0.8d,1.2d,1.5d}; // 每个阶梯的单价
double mountArrs[]={0,500,800,1000}; // 每个阶梯的最小值
double[] valueArrs=new double[4]; // 存储每个阶梯对应的值
getAreaValue(mountArrs,valueArrs,currentMount,needMount);
System.out.println(valueArrs[0]+","+valueArrs[1]+","+valueArrs[2]+","+valueArrs[3]);
}
/**
*
*
* @param mountArrs 每个阶梯量的最小值 ** 这里注意
* @param valueArrs 存储每个阶梯对应的值 (区域单价*区域量)
* @param currentMount 当前使用电量
* @param needMount 还需要电量
*/
public static double[] getAreaValue(double[] mountArrs,double[] valueArrs,double currentMount,double needMount){
int grade=valueArrs.length-1;
double gap=mountArrs[grade];;
double finalvalue=currentMount+needMount;
double leftvale=needMount;
boolean flag=false;
for(int i=grade;i>=0;i--){
if(i==0){
if(flag){
//总每个阶段的钱
valueArrs[i]=finalvalue;
}else{
//购买的每个阶段的钱
valueArrs[i]=leftvale;
}
break;
}
//剩下的=总-每个阶段的电量
double tempvalue=finalvalue-gap;
if(tempvalue>0){
if(flag){ // 说明之前已经 减掉了部分
valueArrs[i]=gap;
finalvalue=leftvale-gap;
}else{
if(tempvalue>leftvale){
valueArrs[i]=leftvale;
break;
}else{
finalvalue=leftvale-tempvalue;
valueArrs[i]=tempvalue;
flag=true;
}
}
leftvale=finalvalue;
gap=mountArrs[i]-mountArrs[i-1];
}else{
if(flag){
valueArrs[i]=finalvalue;
break;
}else{
valueArrs[i]=0;
gap=mountArrs[i-1];
}
}
}
return valueArrs;
}
}
valueArrs里面就存储了 每个阶梯所对应的电量,在根据每个阶梯的单价,相乘相加就可以了,这里最好用bigDecimal 来精确计算。
可能有什么不对的地方,望大家及时纠正指教!