【发布时间】: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