0
点赞
收藏
分享

微信扫一扫

时间区间合并算法

老牛走世界 2022-04-13 阅读 48
算法

目录

需求描述:

时间范围:

2022-04-10 09:00:00 ~ 2022-04-10 10:00:00
2022-04-10 10:00:00 ~ 2022-04-10 11:00:00
2022-04-10 11:00:00 ~ 2022-04-10 12:00:00
2022-04-10 13:00:00 ~ 2022-04-10 17:00:00
2022-04-10 06:00:00 ~ 2022-04-10 08:00:00

具体描述:需要将上边的一个时间列表重叠的部分合并成一个时间范围,并按开始时间升序。
实现效果:

(startTimeStamp=1649541600000, endTimeStamp=1649548800000)
(startTimeStamp=1649552400000, endTimeStamp=1649563200000)
(startTimeStamp=1649566800000, endTimeStamp=1649581200000)

项目依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

代码实现:

@SpringBootTest
public class DemoApplicationTests {
    public static final DateTimeFormatter YYYY_MM_DD = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    public static final DateTimeFormatter YYYY_MM_DD_HH_MM_SS = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Builder
    @Data
    static class IntervalInfo {
        private Long startTimeStamp;
        private Long endTimeStamp;
    }

    @Test
    public void testMergeIntervalInfoList() {
        List<IntervalInfo> intervalInfoList = new ArrayList<>();
        intervalInfoList.add(IntervalInfo.builder().startTimeStamp(getTimeStamp("2022-04-10 09:00:00")).endTimeStamp(getTimeStamp("2022-04-10 10:00:00")).build());
        intervalInfoList.add(IntervalInfo.builder().startTimeStamp(getTimeStamp("2022-04-10 10:00:00")).endTimeStamp(getTimeStamp("2022-04-10 11:00:00")).build());
        intervalInfoList.add(IntervalInfo.builder().startTimeStamp(getTimeStamp("2022-04-10 11:00:00")).endTimeStamp(getTimeStamp("2022-04-10 12:00:00")).build());
        intervalInfoList.add(IntervalInfo.builder().startTimeStamp(getTimeStamp("2022-04-10 12:00:00")).endTimeStamp(getTimeStamp("2022-04-10 13:00:00")).build());
        List<IntervalInfo> result = new ArrayList<>();
        for (IntervalInfo intervalInfo : intervalInfoList) {
            result = mergeIntervalInfoList(result, intervalInfo);
        }
        for (IntervalInfo intervalInfo : result) {
            System.out.println(intervalInfo);
        }
    }

    /**
     * 获取时间戳的微秒数
     *
     * @param time
     * @return
     */
    public Long getTimeStamp(String time) {
        return LocalDateTime.parse(time, YYYY_MM_DD_HH_MM_SS).toInstant(ZoneOffset.of("+8")).toEpochMilli();
    }

    /**
     * 合并交集区间并排序
     *
     * @param intervalInfoList
     * @param newIntervalInfo
     * @return
     */
    public List<IntervalInfo> mergeIntervalInfoList(List<IntervalInfo> intervalInfoList, IntervalInfo newIntervalInfo) {
        //迭代下标索引
        int i = 0;
        //找到合并区间
        while (i < intervalInfoList.size() && intervalInfoList.get(i).getEndTimeStamp() < newIntervalInfo.getStartTimeStamp()) {
            i++;
        }
        //开始合并区间
        while (i < intervalInfoList.size() && intervalInfoList.get(i).getStartTimeStamp() <= newIntervalInfo.getEndTimeStamp()) {
            long min = Math.min(intervalInfoList.get(i).getStartTimeStamp(), newIntervalInfo.getStartTimeStamp());
            long max = Math.max(intervalInfoList.get(i).getEndTimeStamp(), newIntervalInfo.getEndTimeStamp());
            newIntervalInfo = IntervalInfo.builder().startTimeStamp(min).endTimeStamp(max).build();
            intervalInfoList.remove(i);
        }
        intervalInfoList.add(i, newIntervalInfo);
        //返回合并结果
        return intervalInfoList;
    }
}

运行效果:

DemoApplicationTests.IntervalInfo(startTimeStamp=1649541600000, endTimeStamp=1649548800000)
DemoApplicationTests.IntervalInfo(startTimeStamp=1649552400000, endTimeStamp=1649563200000)
DemoApplicationTests.IntervalInfo(startTimeStamp=1649566800000, endTimeStamp=1649581200000)
举报

相关推荐

0 条评论