【问题标题】:Map reducing algorithm地图缩减算法
【发布时间】:2013-04-18 04:13:43
【问题描述】:

我怎样才能reduceMap<Integer, List<Integer>>

reduce'd 映射是一个映射,其中 List<Integer> 的每个 Integer 值都是唯一的且不重复。

例子:

地图A:

 0 --> (0)
 1 --> (1, 2) 
 2 --> (2, 1)

将简化为:

 0 --> (0)
 1 --> (1, 2)

 0 --> (0)
 2 --> (2, 1)

请注意,删除键 1 或 2 都是可以接受的,因为它会生成 reduced 映射。

编辑:当一个元素映射到自身时,它应该保持独立,例如0 --> 0。但是,当多个值具有共同的整数时,它们应该被合并。

【问题讨论】:

  • 你将如何决定删除哪些键和保留哪些键?
  • 好吧,在上面的示例中,key = 12 可能已被删除。让我编辑问题。 key 删除无关紧要,重要的是唯一性和非重复值。 P.S 为什么要关闭?
  • 0 --> (0) 1 --> (1, 2) 2 --> (2, 1, 3) 会发生什么
  • @faisal,reduced 映射将是:0 --> 0, 1 --> (1,2,3)0 --> 0, 2 --> (2,1,3) 值的顺序无关紧要。重要的是唯一性和非重复性。
  • 对于第一个选项 0 --> 0, 1 --> (1,2,3) 为什么 3 是 list1 的一部分,如果是这样,为什么 ans 不是 0 --> (0 ,1,2,3)

标签: java list map


【解决方案1】:

试试这个

class ReducedMap extends HashMap<Integer, List<Integer>> {
    private Set<Set<Integer>> set = new HashSet<Set<Integer>>();

    @Override
    public List<Integer> put(Integer key, List<Integer> value) {
        Set<Integer> set = new HashSet<Integer>(value);
        if (!this.set.add(set)) {
            return new ArrayList<Integer>(set);
        }
        return super.put(key, value);
    }
      ...

【讨论】:

  • 感谢您的回答。明天再试几个小时再看。
【解决方案2】:

保留一个 ArrayList,我们称之为“合并”。

您应该使用 HashSet 来检测重复值。检查一个元素(列表中的值)是否在 HashSet 中,如果是则忽略它,否则将其放入 HashSet 并将其添加到“合并”ArrayList 中。

显然,您必须在此逻辑的开头添加一个案例,以不考虑元素是否映射到自身。

算法将如下所示:

  1. 声明一个名为“ret”的 Map>、一个名为“merged”的 ArrayList 和一个名为“duplicate_checker”的 HashSet

  2. 对于输入地图中的每个列表

    2.1 如果映射到自身,则放入“ret”

    2.2 否则,对于当前列表中的每个元素,如果它不在“duplicate_checker”中,则将其放在那里并添加到“合并”中

  3. 把“merged”换成“ret”

  4. 返回“ret”

希望这会有所帮助。

【讨论】:

  • 感谢您的回答。明天再试几个小时再看。
【解决方案3】:

这样的事情应该可以工作。

第 2 版,第一个有错误

我会使用 Pair 类,因为我们将从地图中提取所有条目并将它们放置在 Pair 的向量中。

private static class Pair {

    public Pair(Integer k, List<Integer> l) {

        this.k = k;
        this.s = new HashSet<Integer>();
        this.s.addAll(l);
    }

    public Integer k;
    public Set<Integer> s;
}

接下来,我们需要一个方法来检查两个集合是否有一些共同的元素。

public static boolean intersect(Set<Integer> a, Set<Integer> b) {

    Set<Integer> tmp = new HashSet<Integer>(a);
    tmp.retainAll(b);

    return !tmp.isEmpty();
}

reduction 方法接受一个映射并返回一个新的缩减映射。

public static Map<Integer, List<Integer>> reduce(Map<Integer, List<Integer>> m) {

首先我们将地图转换为Pair的数组;这将允许有效地迭代和消除键。

    int cnt = 0;
    Pair[] entries = new Pair[m.size()];

    for (Integer k : m.keySet()) {

        List<Integer> l = m.get(k);
        entries[cnt] = new Pair(k, l);
        ++cnt;
    }

然后我们针对任何其他条目测试每个 Pair;如果它们有共同的元素,我们删除后者,但首先我们将其合并到前者中。

    for (int i = 0; i < m.size(); ++i) {

        for (int j = i + 1; j < m.size(); ++j) {

            if (entries[i] != null && entries[j] != null && intersect(entries[i].s, entries[j].s)) {

                Set<Integer> si = entries[i].s;
                Set<Integer> sj = entries[j].s;

                si.addAll(sj);
                entries[j] = null;
            }
        }
    }

最后,我们将数组转换回地图,跳过删除的元素。

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

    for (int i = 0; i < m.size(); ++i)
        if (entries[i] != null)
            r.put(entries[i].k, new ArrayList<Integer>(entries[i].s));

    return r;
}

【讨论】:

    猜你喜欢
    • 2013-10-16
    • 1970-01-01
    • 2014-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-06
    • 1970-01-01
    相关资源
    最近更新 更多