Android会员卡充值方案的实现

情景

产品来了新需求,做一个会员卡充值,可选充多少送多少,也可以输入其他任意金额并计算出送的金额。起初看这个需求还是比较简单的,实际在我做的时候,发现涉及到对算法的要求。

掉坑

服务端返回的充值方案的顺序是递增的(充值金额大的的排到最后),这好办了,输入的充值金额BigDecimal recharge循环从最后一个开始比较,当大于等于集合中的某个充值方案MemberRechargePlan rechargePlan的充值金额时 BigDecimal rechargeAmount,拿到赠送金额并且累加。并且输入的recharge要减去rechargeAmount,break跳出循环后,再进行递归的操作。最终得到应该赠送的金额。

提交测试,测试反馈两个问题:
1.充值方案集合中有相同的充值金额,应该选择最大的赠送金额。
2.输入999999这种大数字的充值金额程序闪退。

解决问题一

对相同充值金额的只保留最大的赠送金额的,其他排除。然后再用冒泡排序法升序排列。代码:

//排重+排序
private void doExDupAndSortList() {
//step1:排重,取最大赠送金额
for (int i = 0; i < listRechargePlan.size() - 1; i++) {
    for (int j = listRechargePlan.size() - 1; j > i; j--) {
        if (listRechargePlan.get(j).getRechargeAmount().compareTo(listRechargePlan.get(i).getRechargeAmount()) == 0) {
            if (listRechargePlan.get(j).getGiftAmount().compareTo(listRechargePlan.get(i).getGiftAmount()) != 1) {
                        listRechargePlan.remove(j);
               } else {
                        listRechargePlan.remove(i);
                    }
                }
            }
        }
//step2:排序
for (int i = 1; i < listRechargePlan.size(); i++) {
     for (int j = 0; j < listRechargePlan.size() - i; j++) {
          if (listRechargePlan.get(j).getRechargeAmount().compareTo(listRechargePlan.get(j + 1).getRechargeAmount()) == 1) {
            MemberRechargePlan temp = listRechargePlan.get(j);
            listRechargePlan.set(j, listRechargePlan.get(j + 1));
            listRechargePlan.set(j + 1, temp);
                }
            }
        }
}

解决问题二

由于输入的充值金额过大,导致了多层递归嵌套,抛出 java.lang.stackoverflowerr堆栈溢出异常。解决方法就是减少递归,代码:

//计算赠送金额
private void countGiftMoney(BigDecimal recharge) {
 boolean haveRecharge = false;
 int size = listRechargePlan.size() - 1;
 for (int i = size; i >= 0; i--) {
  MemberRechargePlan plan = listRechargePlan.get(i);
  if (plan.getRechargeAmount().compareTo(recharge) != 1) {
     BigDecimal[] divide = recharge.divideAndRemainder(plan.getRechargeAmount());
     BigDecimal beishu = divide[0];//倍数
     //加上 赠送金额*倍数
     giftMoney = giftMoney.add(plan.getGiftAmount().multiply(beishu));
    //减去 充值金额*倍数
    recharge = recharge.subtract(plan.getRechargeAmount().multiply(beishu));
   haveRecharge = true;
   break;
   }
  }
  if (haveRecharge && recharge.compareTo(BigDecimal.ZERO) == 1) {
            countGiftMoney(recharge);//递归
   }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值