将两个数组分组为一个常见结果数组

时间:2014-10-23 09:08:16

标签: java arrays math recursion

这是一个我似乎无法理解的逻辑问题。

我希望实现的是将两个具有相同总价值的不同产品中的两种不同产品匹配到包装中。

为简单起见,我们假设有两个[id,price]对

的数组
array1 = [id=A,price=1],[id=B,price=2],[id=C,price=3]
array2 = [id=A,price=2],[id=B,price=1],[id=C,price=1]

我可以通过合并array1 [id A]array2 [id B]来获得最便宜的套餐,价格为2美元 但我也可以将array1 [id A]array2 [id C]结合起来制作一个2美元的套餐。

所以我想要的是一组可以按总值分组的包。但只能根据第一个数组中选择的内容。

例如:(纯粹用于可视化目的):

  package1 :
  total : $2  
    1st option :
      [id=A,price=1]
    2nd option
      [id=B,price=1]
      [id=C,price=1]

  package2 :
  total : $3  
    1st option :
      [id=A,price=1]
    2nd option
      [id=A,price=2]

 package3 :
  total : $3  
    1st option :
      [id=B,price=2]
    2nd option
      [id=B,price=1]
      [id=C,price=1]

等。
我假设我需要递归迭代结果,我只是继续走错路,也许有人可以指出我正确的方向。

3 个答案:

答案 0 :(得分:1)

最佳选择是计算所有组合的结果,并在计算结果时将选项存储到地图结构中。

如果您正在为您的班级使用自定义对象(MyOption):

Map<Integer, Map<MyOption, List<MyOption>> result = new HashMap<>();

或者,如果你正在使用对象数组:

Map<Integer, Map<Object[], List<Object[]>> result = new HashMap<>();

答案 1 :(得分:1)

也许你可以生成[价格]&lt; - &gt; [商品列表]地图,key是价格,value是具有相同价格的商品列表。例如     [1] -- [Item A, Item B], [2] -- [Item D, Item E, Item Z],然后您可以在地图上生成不同的包基。

private void methodToGenerateCombinationOfItems {
    Map<Integer, List<Item>> map = new HashMap<Integer, List<Item>>();
    updateArrayDataToMap(map, array1);
    updateArrayDataToMap(map, array2);
    ... ...
    // now the map should contains [price X] <--> [list of items with price X]
    // if you want to order by price, you may want to use TreeMap instead of HashMap.
}

private void updateArrayDataToMap(Map<Integer, List<Item>> map, List<Item> itemArr) {
    for( Item item : itemArr) {
        if( map.contains(item.getPrice()) ) {
            map.get(item.getPrice()).add(item);
        } else {
            List<Item> listTmp = new ArrayList<Item>();
            listTmp.add(item);
            map.put(item.getPrice(), listTmp);
        }
    }
}

答案 2 :(得分:0)

伪代码:

List<Package> results = new ArrayList<>();
for(Item item:array1) {
    if (item.getPrice() < 2) {
        addAllPackagesStartingWith(item, results);
    }
}

// add all packages where an item from array 1 can be paired with an item in array 2
void addAllPackagesStartingWith(Item item, List<Package> results) {
    for (Item array2Item:array2) {
        if(item.getPrice() + array2Item.getPrice() < 2) {
            results.add(new Package(item, array2Item));
        }
    }
}