php中的多个时间交集

发布于 2024-11-30 02:50:27 字数 392 浏览 4 评论 0原文

我现在遇到了一个我无法理解的情况。多个时间重叠。我看过很多关于两个重叠时间的帖子,但没有看到多次重叠的帖子。

这是我想要放入的数据:

<?php
//RUN EACH Class Selection for Monday
foreach($class as $Classes){
    $time[] = array($ClassStartTime, $ClassEndTime, $classID);
}

OverLapFunction($time);
?>

然后将发布 classID 和重叠金额。以前有人遇到过这种情况吗?或者知道如何做到这一点?

I have a situation that I can not wrap my head around at the moment. Multiple Time Overlaps. I've seen many posts on two times that overlap but nothing that has multiple times overlapping.

Here's the data I would like to place in:

<?php
//RUN EACH Class Selection for Monday
foreach($class as $Classes){
    $time[] = array($ClassStartTime, $ClassEndTime, $classID);
}

OverLapFunction($time);
?>

Which would then post the classID and Overlapping Amount. Has anyone run into this situation before? Or figured out how to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

遇到 2024-12-07 02:50:27

假设您的数据是这样的:

$classes = array(
    array(
       'name' => 'A',
       'day'  => 'Monday',
       'start'=> '08:00AM',
       'end'  => '11:00AM',
    ),
    array(
       'name' => 'B',
       'day'  => 'Monday',
       'start'=> '10:00AM',
       'end'  => '11:30AM',
    ),
    array(
       'name' => 'C',
       'day'  => 'Monday',
       'start'=> '12:00PM',
       'end'  => '04:00PM',
    ),
    array(
       'name' => 'D',
       'day'  => 'Monday',
       'start'=> '03:00PM',
       'end'  => '06:00PM',
    ),
);

您只需要一个嵌套的 foreach,如下所示:

$overlap = array();
foreach ($classes as $class1) {
    foreach ($classes as $class2) {
        if ($class1['day'] != $class2['day'] || $class1 == $class2) continue;
        if (strtotime($class1['start']) <  strtotime($class2['end']) &&
            strtotime($class1['start']) >= strtotime($class2['start']))
        {
            $array = array($class1['name'], $class2['name']);
            sort($array);
            if (!in_array($array, $overlap)) $overlap[] = $array;
        }
    }
}

基本上,它将每个类与所有类进行比较。如果$class1开始时间小于$class2结束时间并且$class1开始时间大于$class2 开始时间:它们重叠。请记住,每个类将相互比较两次(例如:A 到 B、B 到 A),因此如果第一次不匹配,则第二次会匹配。

这将为您提供:

Array
(
    [0] => Array
        (
            [0] => B
            [1] => A
        )

    [1] => Array
        (
            [0] => D
            [1] => C
        )

)

如果您要将类 D 更改为:

array(
   'name' => 'D',
   'day'  => 'Monday',
   'start'=> '10:00AM',
   'end'  => '03:00PM',
),

...有效地重叠所有类,您将得到:

Array
(
    [0] => Array
        (
            [0] => A
            [1] => B
        )

    [1] => Array
        (
            [0] => B
            [1] => D
        )

    [2] => Array
        (
            [0] => C
            [1] => D
        )

    [3] => Array
        (
            [0] => A
            [1] => D
        )

)

Say your data is like this:

$classes = array(
    array(
       'name' => 'A',
       'day'  => 'Monday',
       'start'=> '08:00AM',
       'end'  => '11:00AM',
    ),
    array(
       'name' => 'B',
       'day'  => 'Monday',
       'start'=> '10:00AM',
       'end'  => '11:30AM',
    ),
    array(
       'name' => 'C',
       'day'  => 'Monday',
       'start'=> '12:00PM',
       'end'  => '04:00PM',
    ),
    array(
       'name' => 'D',
       'day'  => 'Monday',
       'start'=> '03:00PM',
       'end'  => '06:00PM',
    ),
);

You just need a nested foreach, like this:

$overlap = array();
foreach ($classes as $class1) {
    foreach ($classes as $class2) {
        if ($class1['day'] != $class2['day'] || $class1 == $class2) continue;
        if (strtotime($class1['start']) <  strtotime($class2['end']) &&
            strtotime($class1['start']) >= strtotime($class2['start']))
        {
            $array = array($class1['name'], $class2['name']);
            sort($array);
            if (!in_array($array, $overlap)) $overlap[] = $array;
        }
    }
}

Basically, it compares each class to all classes. If $class1 start time is less than $class2 end time and $class1 start time is more than $class2 start time: they overlap. Keep in mind that each class will be compared to each other twice (e.g.: A to B, B to A), so if it doesn't match on the first pass, it will in the second.

This'll give you:

Array
(
    [0] => Array
        (
            [0] => B
            [1] => A
        )

    [1] => Array
        (
            [0] => D
            [1] => C
        )

)

If you were to change class D to:

array(
   'name' => 'D',
   'day'  => 'Monday',
   'start'=> '10:00AM',
   'end'  => '03:00PM',
),

...effectively overlapping all classes, you'd get:

Array
(
    [0] => Array
        (
            [0] => A
            [1] => B
        )

    [1] => Array
        (
            [0] => B
            [1] => D
        )

    [2] => Array
        (
            [0] => C
            [1] => D
        )

    [3] => Array
        (
            [0] => A
            [1] => D
        )

)
三生池水覆流年 2024-12-07 02:50:27

免责声明:此函数更多是伪代码,您需要自己实现;它返回重叠类的组。我这样写是为了让你更好地理解。如果您需要更多解释为什么我们需要首先对时间进行排序,请告诉我。

function OverLapFunction($time) {
    sort_by_start_time($time); // ensures that we don't have
                               // overlapping groups at the end
    $groups = array(); // groups have starting time, ending
                       // time and items they contain
    foreach($time as $item) {
        // if we don't find a group to put this item in, we create a new one
        $found = false;
        foreach($groups as $group) {
            // basically the whole if statement looks for overlapping between
            // the group and the current item
            if(($item['start_time'] >= $group['start_time'] 
                && $item['start_time'] <= $group['end_time']) ||
                ($item['end_time'] >= $group['start_time']
                &&  $item['end_time'] <= $group['end_time']))
            $group['items'][] = $item; // add the item to its group
            $found = true;
            break;
        }
        if(!$found) { // no group that fits this item; create a new one
            $groups[] = array(
                'start_time' => $item['start_time'], // start and end times
                'end_time' => $item['end_time'],     // are the item's
                'items' => array($item),
            );
        }
    }
    return $groups;
}

哦,郑重声明一下:如果您有一个用户选择了某些类别,并且您需要确保他选择的类别中没有两个重叠,您可以将问题简化为您已经掌握的问题:

for($i=0; $i<count($item); $i++) {
    for($j=0; $j<count($item); $j++) {
        if($i == $j) {
            continue;
        }   
        if(times_overlap($item[$i], $item[$j])) {
            do_something(); // the user has chosen incorrect classes
        }
    }
}

注意:上面的问题如果您按开始日期对项目进行排序并仅检查两个连续的数组元素是否重叠,则可以提高性能。

Disclaimer: This function is more pseudocode and you'll need to implement it yourself; It returns groups of overlapping classes. I've written it like this for you to understand it better. If you need more explanation on why we need to sort the times first, let me know.

function OverLapFunction($time) {
    sort_by_start_time($time); // ensures that we don't have
                               // overlapping groups at the end
    $groups = array(); // groups have starting time, ending
                       // time and items they contain
    foreach($time as $item) {
        // if we don't find a group to put this item in, we create a new one
        $found = false;
        foreach($groups as $group) {
            // basically the whole if statement looks for overlapping between
            // the group and the current item
            if(($item['start_time'] >= $group['start_time'] 
                && $item['start_time'] <= $group['end_time']) ||
                ($item['end_time'] >= $group['start_time']
                &&  $item['end_time'] <= $group['end_time']))
            $group['items'][] = $item; // add the item to its group
            $found = true;
            break;
        }
        if(!$found) { // no group that fits this item; create a new one
            $groups[] = array(
                'start_time' => $item['start_time'], // start and end times
                'end_time' => $item['end_time'],     // are the item's
                'items' => array($item),
            );
        }
    }
    return $groups;
}

Oh, and for the record: if you have a user that selects some classes and you need to ensure that no two of his chosen classes overlap, you can reduce the problem to the one you already have a grasp on:

for($i=0; $i<count($item); $i++) {
    for($j=0; $j<count($item); $j++) {
        if($i == $j) {
            continue;
        }   
        if(times_overlap($item[$i], $item[$j])) {
            do_something(); // the user has chosen incorrect classes
        }
    }
}

Note: the problem above can be made better performance-wise if you sort the items by starting date and just check if two consecutive array elements overlap.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文