我有各种各样的时间范围,如
10:00 12:00,
21:00 24:00,
11:30 12:00,
08:00 17:00
这些是用户的日程安排。我想从这些范围计算总小时数,但我不想计算重复的时间。如果我计算任何一小时,那么我不想再计算一次。我该怎么办呢。
我正在计算小时数。但我怎么能逃避重复的时间。我已经算过了。
$shifts = "10:00 12:00 | 21:00 24:00| 11:30 12:00|08:00 17:00";
$shifts = explode('|', $shifts);
$sum = 0;
$starts = array();
$ends = array();
foreach($shifts as $shift) {
$times = explode(' ', trim($shift));
$start = explode(':', $times[0]);
$end = explode(':', $times[1]);
$startime = $start[0]*60 + $start[1];
$endtime = $end[0]*60 + $end[1];
$flag = false;
foreach ($starts as $key=>$start) {
if($startime < $start && $endtime > $ends[$key]) {
$diff_old = ($start > $ends[$key]) ? $start - $ends[$key] : $ends[$key] - $start;
$sum = $sum - $diff_old/60;
}
else if($startime > $start && $endtime <= $ends[$key]) {
$flag = true;
continue;
}
}
if($flag)
continue;
$starts[] = $startime;
$ends[] = $endtime;
$diff = $startime > $endtime ? $startime - $endtime : $endtime - $startime;
$sum = $sum + $diff/60;
}
echo $sum;
我是通过上面的代码尝试这个,但它显示错误的答案。因为我不想计算已计算的小时数。这次显示的答案是12,但正确答案是10。
答案 0 :(得分:2)
让我们考虑以下几点。如果我们有两个时间间隔[8, 10]
和[9, 12]
,那么时间间隔的并集长度等于[8, 12]
的长度。
如果我们有两个不相交的间隔([8, 9]
和[10, 11]
),我们不需要进行间隔合并来计算长度。相反,我们可以只取间隔长度的总和。
因此,尝试将间隔集减少到一组不相交的间隔是合乎逻辑的。然后问题变得微不足道。
//Check if [a0, a1] and [b0, b1] are disjoint
function isDisjoint($a, $b) {
if(in_array($a[0], $b) || in_array($a[1], $b)) {
return false;
}
return ($a[0] < $b[0]) ? ($a[1] < $b[0]) : ($a[0] > $b[1]);
}
//Make sure $a and $b are not disjoint before calling.
function mergeIntervals($a, $b) {
return array(min($a[0], $b[0]), max($a[1], $b[1]));
}
//Generate a set of disjoint intervals
function genetrateDisjointSet($set) {
$output = array();
while(!empty($set)) {
$interval = array_pop($set);
$intervalDisjoint = false;
while(!$intervalDisjoint) {
$intervalDisjoint = true;
foreach($set as $key => $value) {
if(!isDisjoint($interval, $value)) {
$interval = mergeIntervals($interval, $value);
unset($set[$key]);
$intervalDisjoint = false;
}
}
}
array_push($output, $interval);
}
return $output;
}
//Calculate the length of the set of intervals
function calcLength($set) {
$set = genetrateDisjointSet($set);
$length = 0;
foreach($set as $value) {
$length += $value[1] - $value[0];
}
return $length;
}
我们尝试使用您的示例
//You have to convert the time to minutes after 00:00.
$set = array(
array(600, 720),
array(1260, 1440),
array(690, 720),
array(480, 1020)
);
echo calcLength($set); //720 min = 12 h * 60
注意 08:00
至17:00
+ 21:00
至24:00
为9 + 3 = 12
修改将时间更改为00:00
而非数小时后的分钟数。感谢Dharman的想法。