0

A類時間:如何檢查每天的時間跨度衝突?

Day 1 => 08:00-09:00 | 11:00-12:00 | 13:00-15:00 | 20:00-21:00 
Day 2 => 12:00-13:00 | 14:00-15:00 
Day 3 => 08:00-09:00 | 16:00-17:00 | 18:00-19:00 
Day 4 => 10:00-11:00 | 12:00-14:00 | 14:00-16:00 
Day 5 => 08:00-10:00 | 13:00-15:00 
Day 6 => 80:00-09:00 | 10:00-11:00 

B類時間:

Day 1 => 10:00-11:00 | 17:00-19:00 
Day 2 => 08:00-09:00 | 11:00-12:00 
Day 3 => 08:00-09:00 | 17:00-18:00 | 20:00-21:00 
Day 4 => 08:00-09:00 | 14:00-16:00 | 17:00-18:00 
Day 5 => 08:00-10:00 | 14:00-15:00 
Day 6 => 10:00-11:00 

如何檢查兩個上課時間衝突

+2

你的問題不清楚,請提供你的意圖更多/更好的細節。給你的輸入數組有什麼預期的結果? – mickmackusa

+1

會說現在還不清楚。你是否期望評估'$ stime1 [0]> $ stime2 [0]'?或者是否希望將所有時間加起來(例如08:00 + 11:00 = 19:00等),然後比較它們? ...你如何給出你想要的結果,以及起點(你有什麼,所以離開那裏),然後告訴我們你是如何/你試圖完成的結果?這對我們有幫助的靈魂會有幫助;) – Nukeface

+0

@InformationArtist我沒有被你原來的帖子的複雜性所嚇倒,我只是想看到你想要的結果更加清晰。我不是速度海報,我喜歡具有挑戰性的問題。這裏有一些相似的答案:https://stackoverflow.com/a/45156381/2943403現在,考慮到你的兩個單獨的批次的輸入數據,你預期的結果是什麼? – mickmackusa

回答

0

因爲重疊時段可能不一個簡單的==比較,cl屁股時段必須分成開始和結束塊並單獨處理。不幸的是,這會產生一個循環繁重的代碼塊 - 但這是不可避免的。

array_walk_recursive()用於準備您的輸入數據。該功能在設計上僅迭代$sched的「葉節點」 - 這意味着$v永遠不會是一個數組,它將始終是一個時間跨度字符串。該功能也是「深度無知的」,因此正確修改原始$sched數據的唯一方法是使$v可通過參考進行修改(請參閱:&$v)。

一旦數據重構後,是時候變得糟糕了。一系列3個連續的循環遍歷「目標」類和日子子陣列進行比較。另外2個循環用於訪問所有其他類的相同Day子數組(週期)。之前的代碼再次執行array_walk_recursive()以減少總循環,但這不是最佳實踐,因爲使用foreach循環提前退出並使用break(2)可節省迭代次數並提高效率。

假設某些類可能沒有周期的一天,我在一天檢查中烘烤以確保我的方法不會導致基於丟失的Day子陣列的Notices/Warnings。

代碼:(Demo

$sched=[ 
    'Class A'=>[ 
     'Day 1'=>['10:00-11:00','11:00-12:00','13:00-15:00','20:00-21:00'], 
     'Day 2'=>['12:00-13:00','14:00-15:00'], 
     'Day 3'=>['08:00-09:00','16:00-17:00','18:00-19:00'], 
     'Day 4'=>['10:00-11:00','12:00-14:00','14:00-16:00'], 
     'Day 5'=>['08:00-10:00','13:00-15:00'], 
     'Day 6'=>['08:00-09:00','10:00-11:00'] 
    ], 
    'Class B'=>[ 
     'Day 1'=>['09:30-10:30','17:00-19:00'], 
     'Day 2'=>['08:00-09:00','11:00-12:00'], 
     'Day 3'=>['08:00-09:00','17:00-18:00','20:00-21:00'], 
     'Day 4'=>['08:00-09:00','14:00-16:00','17:00-18:00'], 
     'Day 5'=>['08:00-10:00','14:00-15:00'], 
     'Day 6'=>['10:00-11:00'] 
    ], 
    'Class C'=>[ 
     'Day 1'=>['12:00-14:00'] 
    ] 
]; 
// Preparation: Split the dashed time spans into chunked subarrays containing start and end times 
// e.g. $sched['Class A']['Day 1'][['10:00','11:00'],['17:00','19:00']] 
array_walk_recursive($sched,function(&$v){$v=explode('-',$v);}); 

// Comparisons: 
foreach($sched as $class=>$days){ 
    $other_classes=array_diff_key($sched,[$class=>'']); // same array without target class 
    foreach($days as $day=>$spans){ 
     //echo "\n\n$class, $day"; 
     foreach($spans as $period=>$span){ 
      //echo "\nchecking {$span[0]} & {$span[1]}"; 
      foreach($other_classes as $other_class=>$other_days){ 
       if(isset($other_days[$day])){ // this avoids Notices/Warning about non-existent day in class 
        foreach($other_days[$day] as $other_period=>$other_span){ // compare other classes on same day 
         //echo "\nversus {$other_span[0]} & {$other_span[1]}"; 
         if(($span[0]>=$other_span[0] && $span[0]<$other_span[1]) || ($span[1]<=$other_span[1] && $span[1]>$other_span[0])){ 
          $result[]="Clash: $class,$day#".++$period.": {$span[0]}-{$span[1]} vs $other_class,$day#".++$other_period.": {$other_span[0]}-{$other_span[1]}"; 
          break(2); // no need to further check this $span for clashes 
         } 
        } 
       } 
      } 
     } 
    } 
} 
echo implode("\n",$result);