首页 > 解决方案 > Java 从父时间范围中减去时间范围数组

问题描述

时间范围(代表视频长度)采用这种格式的字符串:HH:mm:ss. 假设我有一个看起来像这样的父时间范围:00:00:59表示一个 59 秒长的视频。

我现在有一组时间范围对,我必须从视频中删除,因为在这些时间范围内视频中没有发生任何有趣的事情。例如输入数组:

[
00:00:10 to 00:00:20, 
00:00:30 to 00:00:35, 
00:00:35 to 00:00:40
]

我希望从 59 秒的视频中删除这些不重要的范围,并计算剩余的有效视频片段。在上述情况下,理想的输出将是:

[
00:00:00 to 00:00:10, 
00:00:20 to 00:00:30, 
00:00:40 to 00:00:59
]

标签: java-time

解决方案


Sort, iterate, and include

  1. Sort the input intervals on their start time(to be excluded)
  2. Iterate over each of the input interval to excluded
  3. Include any interval between end of previous excluded interval and start of current excluded interval
  4. At the end, check for any remaining interval by comparing with total length
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class SequenceTest {

    public static void main(String[] args) {
        final SequenceTest sequenceTest = new SequenceTest();
        sequenceTest.computeIncludeIntervals(59,
            Arrays.asList((new int[][]{{10, 20}, {30, 35}, {35, 40}})));
        sequenceTest.computeIncludeIntervals(40,
            Arrays.asList((new int[][]{{10, 20}, {30, 35}, {35, 40}})));
        sequenceTest.computeIncludeIntervals(41,
            Arrays.asList((new int[][]{{10, 20}, {30, 35}, {35, 40}})));
        sequenceTest.computeIncludeIntervals(41,
            Arrays.asList((new int[][]{{0, 20}, {30, 35}, {36, 40}})));

    }

    protected List<int[]> computeIncludeIntervals(final int totalLength, List<int[]> excludeIntervals) {
        // sort the sequence by start time - O(NlogN)
        excludeIntervals.sort((a, b) -> a[0] == b[0] ? Integer.compare(a[1], b[1])
            : Integer.compare(a[0], b[0]));

        int previousEnd = 0; // initial state
        final List<int[]> result = new ArrayList<>();
        for (int[] exclude : excludeIntervals) {
            if (previousEnd < exclude[0]) {
                int[] include = new int[]{previousEnd, exclude[0]};
                result.add(include);
            }
            previousEnd = Math.max(previousEnd, exclude[1]);
        }

        // remaining tail
        if (previousEnd < totalLength) {
            result.add(new int[]{previousEnd, totalLength});
        }

        System.out.println("Total Length: " + totalLength + ", Input: " + excludeIntervals.stream()
            .map(interval -> interval[0] + ":" + interval[1])
            .collect(Collectors.joining(", ")));
        System.out.println("Included: " + result.stream().map(interval -> interval[0] + ":" + interval[1])
            .collect(Collectors.joining(", ")));

        return result;
    }
}

Actual solution

  1. Write a transformer to transform input date time to epoch unix time
  2. Use the above approach to compute include intervals
  3. Transform include intervals in epoch time to date time using reverse transformer

推荐阅读