如何有效地减少必须检查所有可能组合排列的项目集合?

问题描述

假设你得到了这个界面:

public interface Item {
    boolean canCombine(Item other);

    Item combine(Item other);

如果 Item.canCombine(other) 返回 true,则可以将两个项目合并并简化为一个项目。

给定可以组合的这些项目的集合,您将如何有效地减少集合,以便组合每个可以组合的项目。编辑:如果两个项目组合在一起,并且这些项目中的任何一个项目可以与另一个项目组合,那么该组合可以与另一个项目组合。 (A&B可组合,B&C可组合,AB可与C组合)。

我对此的尝试是使用队列并弹出第一项并将其用作累加器。然后我遍历其余的 Collection 并将任何匹配项与累加器组合并删除它们。最后我把累加器放在队列的末尾,这样它就可以进一步减少。 虽然这是 O(n^2) 或更糟。我怀疑有更有效的解决方案。

    static Collection<Item> reduce(Deque<Item> items) {
        Item accumulator;
        var noMatches = new ArrayList<Item>();
        while ((accumulator = items.pollFirst()) != null) {
            boolean matched = false;
            for (Iterator<Item> otherIterator = items.iterator(); otherIterator.hasNext(); ) {
                Item next = otherIterator.next();
                if (accumulator.canCombine(next)) {
                    accumulator = accumulator.combine(next);
                    otherIterator.remove();
                    matched = true;
                }
            }
            if (matched) {
                items.addLast(accumulator);
            } else {
                noMatches.add(accumulator);
            }
        }
        items.addAll(noMatches);
        return items;
    }

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)