经典根据金额拆单问题

今天朋友找我帮忙做一个笔试题,看了一下确实是一个经典的根据金额拆单的使用题目,题目如下:

根据购物车的商品,生成相应的交易订单,根据如下规则

1、每笔交易订单可以有多个商品

2、每笔交易订单的商品只能是同一个卖家

3、每笔交易商品的总价格不能超过1000元

4、生成的交易订单数量最小

看了一下这个题目,其中第2点确实没有什么意思, 这个题目的要求是第3点,第4点为最优解的度量

直接贴源码吧:

package com.karl.order.split;

public class Item {

    private int price;
    private int saleId;

    public Item(int price, int saleId) {
        this.price = price;
        this.saleId = saleId;
    }

//省略getter setter

    @Override
    public String toString() {
        return "[" +
                "price=" + price +
                ", saleId=" + saleId +
                ']';
    }
}

订单类:

package com.karl.order.split;

import java.util.ArrayList;
import java.util.List;

public class Order { 

 private List list = new ArrayList(); 
    public List getList() {
        return list;
    }

    public void addItem(Item item) {
        this.list.add(item);
    }

    public long totalPrice() {
        return list.stream().map(i->i.getPrice()).reduce((a,b)->a+b).get();
    }

    @Override
    public String toString() {
        return list.toString();
    }
}

拆单实现类:

package com.karl.order.split;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import java.util.List;
import java.util.stream.Collectors;
public class SplitOrder { 
     private static int MAX_PRICE = 1000; 
     public static void main(String[] args) { 
        List orders = group(buildItems2());
        System.out.println(orders.size());
     }

     private static List split(List items) {
        items.sort((o1, o2) -> o2.getPrice() - o1.getPrice());
        List orders = new ArrayList();
        while (items.size()>0) {
            Order order = new Order();
            List bestItems = getBestItem(items);
            order.getList().addAll(bestItems);
            orders.add(order);
        }
        return orders;
    }

    private static List getBestItem(List items) {
        List bestGroupIndexs = null;
        int max = 0;
        outer:for(int i=0, size = items.size(); i
            if(bestGroupIndexs != null && bestGroupIndexs.contains(i)) {
                continue;
            }

            if(items.get(i).getPrice() > MAX_PRICE) {
                continue;
            }
            List list = new ArrayList();
            int totalPrice = items.get(i).getPrice();
            list.add(i);
            if (totalPrice >= max) {
                bestGroupIndexs = list;
                max = totalPrice;
            }
            if(i==size -1 || totalPrice >= MAX_PRICE) {
                break;
            }
            for(int j=i+1; j<=size-1; j++) {
                if (totalPrice + items.get(j).getPrice() <= MAX_PRICE) {
                    totalPrice += items.get(j).getPrice();
                    list.add(j);
                    if (totalPrice > max) {
                        max = totalPrice;
                        bestGroupIndexs = list;
                    }
                    if(totalPrice>=MAX_PRICE) {
                        break outer;
                    }
                }
            }
        }
        List ret = new ArrayList();
        Collections.reverse(bestGroupIndexs);
        for(Integer i : bestGroupIndexs) {
            ret.add(items.remove(i.intValue()));
        }
        return ret;
    }
}

你可能感兴趣的:(经典根据金额拆单问题)