算是個面試題吧,問題描述是這樣:多個業務訂單,對應一個支付單進行支付,支付時使用了組合支付。那麼沒個訂單分配到的支付方式及金額如何計算。 一共三個支付方式組合A,B,C金額分辨占100,100,80. 一共兩個訂單1訂單金額80,2訂單金額200. 分配後,產生4份訂單和支付方式不同的數據。 畫個圖 ...
算是個面試題吧,問題描述是這樣:多個業務訂單,對應一個支付單進行支付,支付時使用了組合支付。那麼沒個訂單分配到的支付方式及金額如何計算。 一共三個支付方式組合A,B,C金額分辨占100,100,80. 一共兩個訂單1訂單金額80,2訂單金額200. 分配後,產生4份訂單和支付方式不同的數據。 畫個圖明瞭一點: 問題抽象: 我們發現圖一和圖二重疊一下不就是圖三的分配結果嘛。 可是代碼似乎沒這麼簡單就可以操作。 又將問題擬物化,便於理解,將支付方式組合可以想象成不通種類的杯子,而訂單組合是不同種類的酒,現在要把酒放到輩子里去。每倒一次算一個訂單和支付方式組合的數據。 第一次:1號酒開始到,在A杯子里都倒不滿,直接全部倒光。數據為1+A+80 第二次:2號酒倒入A剩下的20雨量滿了。數據為2+A+20 第三次:2號酒倒入B杯子,倒滿100,2號酒還剩80。數據為2+B+100 第四次:2號酒倒入C杯子,倒滿也到光了。數據為2+C+80 我們發現這四次操作就是遍歷訂單組合的數據,依次去占有剩餘支付金額的數據。而2,3,4次是一個迭代的代碼過程。
如果你剛好有時間,可以自己用熟悉的代碼實現一下,貼出來討論討論。
所以一種實現如下:
public class ItemDistribution { private List<Entry> cupList = new ArrayList<>(); /** * 初始化 * @param list */ public ItemDistribution(List<Item> list) { if(list == null || list.size()<=0){ return; } Integer start = 0; Integer end = 0; for(Item item : list){ end = start + item.amount; Entry entry = new Entry(start, end, item.payMethod); start = end; cupList.add(entry); } } /** * 分配 * @param orderIdAmountMap * @return */ public List<Item> getOrderInfoItemList(Map<Integer, Integer> orderIdAmountMap){ if(cupList == null){ return null; } List<Entry> cupTransferList = cupList; List<Item> returnItems = new ArrayList<>(); for (Map.Entry<Integer, Integer> orderIdAmountEntry : orderIdAmountMap.entrySet()) { Integer orderId = orderIdAmountEntry.getKey(); Integer orderAmount = orderIdAmountEntry.getValue(); buildItem(orderId, orderAmount, cupTransferList, returnItems); } return returnItems; } /** * 單個cup分配 * @param orderId * @param orderAmount * @param cupList * @param returnItems */ private void buildItem(Integer orderId, Integer orderAmount, List<Entry> cupList, List<Item> returnItems) { if(IntegerUtil.isZero(orderAmount) || orderId == null){ return; } Entry cup = getLatestCup(cupList); if(cup == null){ return; } Integer remain = cup.end - cup.index; Item item = null; if(remain > orderAmount){ cup.index = cup.start + orderAmount; item = new Item(orderId, orderAmount, cup.payMethod); returnItems.add(item); return; }else{ cup.index = cup.end; item = new Item(orderId, remain, cup.payMethod); returnItems.add(item); orderAmount = orderAmount - remain; } buildItem(orderId, orderAmount, cupList, returnItems); } /** * 獲得可用的cup * @param cupTransferList * @return */ private Entry getLatestCup(List<Entry> cupTransferList){ for(Entry cup : cupTransferList){ if(!IntegerUtil.isEquals(cup.index, cup.end)){ return cup; } } return null; } public class Entry{ private Integer start; private Integer end; private Integer index = 0; private Integer payMethod; public Entry(Integer start, Integer end, Integer payMethod) { this.start = start; this.index = start; this.end = end; this.payMethod = payMethod; } } public static void main(String[] args) { List<Item> list = new ArrayList<Item>(); Item OrderPayInfoItem1 = new Item(100,1); Item OrderPayInfoItem2 = new Item(100,2); Item OrderPayInfoItem3 = new Item(80,3); list.add(OrderPayInfoItem1); list.add(OrderPayInfoItem2); list.add(OrderPayInfoItem3); ItemDistribution itemDistribution = new ItemDistribution(list); Map map = new HashMap<>(); map.put(1001, 80); map.put(1002, 200); List<Item> returnList = itemDistribution.getOrderInfoItemList(map); } }