kav*_*sis 9 java sorting algorithm
我来这里有一个我想分享的问题,希望有人能帮助我解决这个问题.我会尝试尽可能清楚地描述问题.问题如下.
我有一个java程序,有一个接收一组日期的方法(java.util.Date).
| start end |
| date1 date1|
<--------------->
| | start end | | |
| | date2 date2| | |
| <-------------------> | |
| | start end |
| | date3 date3|
| <------------------->
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,我们有三个日期,前两个相交,但start-date3在end-date2之后.对于我的商业规则,这是一个时间空间.
现在考虑下一个场景.
| start end |
| date1 date1|
<--------------->
| | start end | | |
| | date2 date2| | |
| <-------------------> | |
| | start end |
| | date3 date3|
| <------------------->
| | |
| | start end |
| | date4 date4|
| <------------------------------------------------------>
Run Code Online (Sandbox Code Playgroud)
在这种情况下,即使在end-date2和start-date3之间存在时间空间,也认为它不存在时间空间,因为start-date4和end-date4之间的时间覆盖了这样的空间.
我想检索true,如果有一个或多个时间空间,否则我将返回false.
我试过的唯一方法是循环每个开始/结束关系,比较end-date1 vs start-date2 vs start-date3等等......这不是我想要应用的.
如果有其他一些想法,欢迎他们.如果您需要更多信息,我会添加它.谢谢.
好吧,这确实是一个“奇怪”的想法,但是看看这个“概念”是否更好。
基本上,这个想法是将所有重叠的日期尽可能合并到几个“范围”中,这意味着,在第一个示例中,您最终会得到两个不同的范围(开始日期 1 到结束日期 2 和(开始日期 3到结束日期 3),在第二个时间里,您将得到一个(开始日期 1 到结束日期 4)
因此,如果该集合只有一个不同的范围,那么就没有间隙,否则就没有间隙。
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
public class TestDateRanges {
public static void main(String[] args) {
try {
List<Date[]> dates = new ArrayList<>(
Arrays.asList(
new Date[][]{
{makeDate("1.1.2015"), makeDate("5.1.2015")},
{makeDate("3.1.2015"), makeDate("10.1.2015")},
{makeDate("15.1.2015"), makeDate("20.1.2015")},}
)
);
Collections.sort(dates, new Comparator<Date[]>() {
@Override
public int compare(Date[] o1, Date[] o2) {
return o1[0].compareTo(o2[0]);
}
});
List<Date[]> ranges = new ArrayList<>(dates.size());
Date[] baseRange = null;
for (Date[] range : dates) {
if (baseRange == null) {
baseRange = range;
ranges.add(baseRange);
} else if ((baseRange[0].before(range[0]) || baseRange[0].equals(range[0])) && (baseRange[1].after(range[0]) || baseRange[1].equals(range[0])) {
System.out.println("> Overlap " + format(baseRange) + " <-> " + format(range));
if (range[1].after(baseRange[1])) {
baseRange[1] = range[1];
}
} else {
System.out.println("> Out of range " + format(baseRange) + " >-< " + format(range));
baseRange = range;
ranges.add(baseRange);
}
}
System.out.println("Has " + ranges.size() + " distinct ranges");
for (Date[] range : ranges) {
System.out.println(format(range));
}
} catch (ParseException exp) {
exp.printStackTrace();
}
}
public static final DateFormat FORMAT = new SimpleDateFormat("d.M.yyyy");
protected static final Date makeDate(String value) throws ParseException {
return FORMAT.parse(value);
}
private static String format(Date[] baseRange) {
return FORMAT.format(baseRange[0]) + "->" + FORMAT.format(baseRange[1]);
}
private static Date[] makeDateRange(String from, String to) throws ParseException {
return new Date[]{makeDate(from), makeDate(to)};
}
}
Run Code Online (Sandbox Code Playgroud)
哪个输出...
> Overlap 1.1.2015->5.1.2015 <-> 3.1.2015->10.1.2015
> Out of range 1.1.2015->10.1.2015 >-< 15.1.2015->20.1.2015
Has 2 distinct ranges
1.1.2015->10.1.2015
15.1.2015->20.1.2015
Run Code Online (Sandbox Code Playgroud)
现在,如果我将设置更改为...
List<Date[]> dates = new ArrayList<>(
Arrays.asList(
new Date[][]{
{makeDate("1.1.2015"), makeDate("5.1.2015")},
{makeDate("3.1.2015"), makeDate("10.1.2015")},
{makeDate("15.1.2015"), makeDate("20.1.2015")},
makeDateRange("2.1.2015", "25.1.2015")
}
)
);
Run Code Online (Sandbox Code Playgroud)
它输出...
> Overlap 1.1.2015->5.1.2015 <-> 2.1.2015->25.1.2015
> Overlap 1.1.2015->25.1.2015 <-> 3.1.2015->10.1.2015
> Overlap 1.1.2015->25.1.2015 <-> 15.1.2015->20.1.2015
Has 1 distinct ranges
1.1.2015->25.1.2015
Run Code Online (Sandbox Code Playgroud)
这只是一个概念性的想法,您应该注意,此示例将更改列表中的数据dates,因此您需要确保首先拥有数据的副本