【问题标题】:Interval set in javajava中设置的时间间隔
【发布时间】:2013-03-01 02:03:58
【问题描述】:

我有一个带有整数值的区间列表 [例如。 [1, 4], [10, 19] 等]。有没有办法将这些间隔放入一些 java 集合的容器中 [例如。设置] 这样我就可以在容器上调用“联合”函数。 “联合”函数应该给我一个间隔列表,这样如果任何 2 个插入的间隔重叠,那么它们应该合并到输出中。 我尝试在 Guava 中使用 Range 类,但最终在合并之前将所有间隔相互比较。对此的优雅方法将不胜感激!这是我根据下面的回复尝试过的。输出为 [[1, 15], [17, 20]],正确。我想知道是否有一些现有的 API 实现了这样的功能。

public static void main(String[] args) {
    // mock data
    List<MyIntRange> rng_lst = new ArrayList<Junk.MyIntRange>();
    rng_lst.add(new MyIntRange(1, 10));
    rng_lst.add(new MyIntRange(5, 15));
    rng_lst.add(new MyIntRange(17, 20));

    // sort intervals by start position
    Collections.sort(rng_lst);

    // merge the intervals which overlap
    List<MyIntRange> res_lst = new ArrayList<Junk.MyIntRange>();
    MyIntRange old_rng = null;
    for (MyIntRange cur_rng : rng_lst) {
        if (old_rng == null) {
            old_rng = cur_rng;
        } else {
            if (old_rng.rng.upperEndpoint() < cur_rng.rng.lowerEndpoint()) {
                // this does not over lap with the next one
                res_lst.add(old_rng);
                old_rng = cur_rng;
            } else {
                // overlap
                old_rng = new MyIntRange(old_rng.rng.lowerEndpoint(),
                        cur_rng.rng.upperEndpoint());
            }
        }
    }
    // add the last range
    res_lst.add(old_rng);

    // done!
    System.out.println(res_lst);
}

// wrapper around Guava's Range to make it comparable based on the
// interval's start
public static class MyIntRange implements Comparable<MyIntRange> {
    Range<Integer> rng;

    public MyIntRange(int start, int end) {
        rng = Ranges.closed(start, end);
    }

    public int compareTo(MyIntRange that) {
        int res = -1;
        if (this.rng.lowerEndpoint() > that.rng.lowerEndpoint()) {
            res = 1;
        }
        return res;
    }

    public String toString() {
        return "[" + rng.lowerEndpoint() + ", " + rng.upperEndpoint() + "]";
    }
}

谢谢

【问题讨论】:

  • 是的,有一种方法可以做您想做的事情。 What have you tried?
  • @user1998031 如果 [9,13] 和 [10,15] 那么您期望的结果是什么?
  • 类似于this question?
  • 更新了我正在使用的代码

标签: java algorithm guava intervals interval-tree


【解决方案1】:

这基本上正是RangeSet 在刚刚发布的 Guava 14.0 中所做的,除了它为您进行合并,而不是告诉您可以合并哪些范围。

【讨论】:

  • 这正是我想要的! Guava 中是否有相应的 RangeTree 类,它实现了一个区间树来回答问题,比如找到最接近某个点或区间的区间?
  • 不,没有。不过,您可能可以通过查看某个点之前和之后的subRangeSetspanRangeSet 推导出它。
【解决方案2】:

基本算法:

  1. 按开始索引对区间进行排序
  2. 浏览列表。对于ith 项目:
    1. 比较i 的结束索引和(i+1)st 项的开始索引。
    2. 如果结束索引较大,则将i的结束索引设置为i+1的结束索引,并删除i+1元素。 (这会将它们合并。)

时间复杂度:O(nlgn),因为初始排序。 (也就是说,如果删除操作正确。)

【讨论】:

    猜你喜欢
    • 2020-06-21
    • 2016-02-13
    • 2023-01-12
    • 2018-06-26
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-05
    相关资源
    最近更新 更多