#java-time
#java-time
Вопрос:
Временные диапазоны (представляющие длины видео) представлены в строках этого формата: 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
]
Комментарии:
1. Я бы не искал библиотеку, а рассматривал это как упражнение по алгоритмам.
2.
java.time.Duration
иLocalTime
.
Ответ №1:
Сортировка, итерация и включение
- Сортируйте входные интервалы по времени их начала (должны быть исключены)
- Выполните итерацию по каждому входному интервалу, чтобы исключить
- Включает любой интервал между концом предыдущего исключенного интервала и началом текущего исключенного интервала
- В конце проверьте наличие любого оставшегося интервала путем сравнения с общей длиной
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 resu<
}
}
Фактическое решение
- Напишите преобразователь для преобразования входной даты и времени в эпоху времени unix
- Используйте описанный выше подход для вычисления интервалов включения
- Преобразование включает интервалы в эпохальное время в текущее время с использованием обратного преобразования
Ответ №2:
Я написал 2 класса: TimeRange и TimeRangeSet.
Использование:
public static void main(String[] args) throws ParseException
{
TimeRange minuend = new TimeRange("00:00:00", "00:00:59");
TimeRangeSet subtrahendSet = new TimeRangeSet();
subtrahendSet
.addRange("00:00:10", "00:00:20")
.addRange("00:00:30", "00:00:35")
.addRange("00:00:35", "00:00:40");
TimeRangeSet differenceSet = minuend.minus(subtrahendSet);
System.out.println("t " minuend);
System.out.println("minust" subtrahendSet);
System.out.println("equalst" differenceSet);
}
Вывод:
00:00:00 to 00:00:59
minus [00:00:10 to 00:00:20, 00:00:30 to 00:00:35, 00:00:35 to 00:00:40]
equals [00:00:00 to 00:00:10, 00:00:20 to 00:00:30, 00:00:40 to 00:00:59]
Диапазон времени:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.temporal.ValueRange;
public class TimeRange implements Comparable <TimeRange>
{
private ValueRange valueRange;
private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
public TimeRange(ValueRange valueRange)
{
this.valueRange = valueRange;
}
public TimeRange(String fromTime, String toTime) throws ParseException
{
this
(
ValueRange.of(simpleDateFormat.parse(fromTime).getTime(), simpleDateFormat.parse(toTime).getTime())
);
}
public TimeRangeSet minus(TimeRangeSet subtrahendSet)
{
TimeRangeSet difference = new TimeRangeSet();
subtrahendSet.forEach
(
(subtrahend) ->
{
TimeRangeSet subDifference = new TimeRangeSet();
subDifference.addAll(minus(subtrahend));
difference.addAll(subDifference.minus(subtrahendSet));
}
);
return difference;
}
public TimeRangeSet minus(TimeRange subtrahend)
{
TimeRangeSet difference = new TimeRangeSet();
long A = valueRange.getMinimum();
long B = valueRange.getMaximum();
long C = subtrahend.valueRange.getMinimum();
long D = subtrahend.valueRange.getMaximum();
if ( B <= C ) // A-----------B
difference.addRange(ValueRange.of(A, B)); // C-------D
else
if ( A >= D ) // A-----------B
difference.addRange(ValueRange.of(A, B)); // C-------D
else
if ( (A >= C) amp;amp; (A < D) amp;amp; (B > D) ) // A---------------B
difference.addRange(ValueRange.of(D, B)); // C-------D
else
if ( (A < C) amp;amp; (B > C) amp;amp; (B <= D) ) // A---------------B
difference.addRange(ValueRange.of(A, C)); // C-------D
else
if ( (A < C) amp;amp; (B > C) amp;amp; (B > D) ) // A---------------B
{ // C-------D
difference.addRange(ValueRange.of(A, C));
difference.addRange(ValueRange.of(D, B));
}
return difference;
}
public String toString()
{
return String.format("%tT to %tT", valueRange.getMinimum(), valueRange.getMaximum());
}
@Override
public int compareTo(TimeRange input)
{
return this.toString().compareTo(input.toString());
}
}
TimeRangeSet:
import java.text.ParseException;
import java.time.temporal.ValueRange;
import java.util.TreeSet;
public class TimeRangeSet extends TreeSet <TimeRange>
{
private static final long serialVersionUID = 1L;
public TimeRangeSet addRange(ValueRange valueRange)
{
super.add(new TimeRange(valueRange));
return this;
}
public TimeRangeSet addRange(String fromTime, String toTime) throws ParseException
{
super.add(new TimeRange(fromTime, toTime));
return this;
}
public TimeRangeSet minus(TimeRangeSet subtrahendSet)
{
subtrahendSet.forEach
(
(subtrahend) ->
((TimeRangeSet) this.clone()).forEach
(
(minuend) ->
{
if (this.addAll(minuend.minus(subtrahend)))
this.remove(minuend);
}
)
);
return this;
}
}