2012-02-23 25 views
1

我有一個asbolute噩夢處理的數字陣列,其具有以下結構:分離數組有效

奇數數組中:NumberRepresenting週數組
即使號碼:NumberRepresenting時間

因此,例如在陣列中:

index : value 
0 : 9 
1 : 1 
2 : 10 
3 : 1 

將意味着在第1天(星期一)9 + 10。

問題是,我有一個不可預知的數字,我需要計算出每天有多少「會話」。會話的規則是,如果他們在不同的日子,他們會自動進行不同的會話。如果它們彼此相鄰,就像示例9 + 10中那樣將被視爲單個會話。最大數量可以直接放在eachother旁邊。3.在此之後,至少需要1個會話中斷才能算作新會話。

不幸的是,我們不能也假設數據將被排序。它將始終遵循偶數/奇數模式,但可能不會將邏輯上彼此相鄰的會話存儲在數組中。

我需要計算出有多少會話。

到目前爲止我的代碼如下:

for($i = 0; $i < (count($TimesReq)-1); $i++){ 
    $Done = false; 
    if($odd = $i % 2) 
    { 
    //ODD WeekComp 
     if(($TimesReq[$i] != $TimesReq[$i + 2])&&($TimesReq[$i + 2] != $TimesReq[$i + 4])){ 
     $WeeksNotSame = true; 
     } 
    } 
    else 
     { 
     //Even TimeComp 

     if(($TimesReq[$i] != ($TimesReq[$i + 2] - 1))&& ($TimesReq[$i + 2] != ($TimesReq[$i + 4] - 1))) 
     $TimesNotSame = true; 
     } 
    if($TimesNotSame == true && $Done == false){ 
    $HowMany++; 
    $Done = true; 
    } 
    if($WeeksNotSame == true && $Done == false){ 
    $HowMany++; 
    $Done = true; 
    } 
$TimesNotSame = false; 
$WeeksNotSame = false; 
    } 

然而,這不是完美的工作。例如,如果您有單個會話,然後休息然後雙重會話,則它不起作用。它將這算作一個會話。

這可能就像你猜測的那樣是一門課程問題,但這不是課本中的問題,它是我正在實施的時間表系統的一部分,並且需要它來運行。所以請不要以爲我只是把我的作業複製粘貼給你們!

非常感謝!

新代碼被使用:

if (count($TimesReq) % 2 !== 0) { 
//throw new InvalidArgumentException(); 
} 

for ($i = 0; $i < count($TimesReq); $i += 2) { 

    $time = $TimesReq[$i]; 
    $week = $TimesReq[$i + 1]; 

    if (!isset($TimesReq[$i - 2])) { 
     // First element has to be a new session 
     $sessions += 1; 
       $StartTime[] = $TimesReq[$i]; 
       $Days[] = $TimesReq[$i + 1]; 
     continue; 
    } 

    $lastTime = $TimesReq[$i - 2]; 
    $lastWeek = $TimesReq[$i - 1]; 

    $sameWeek = ($week === $lastWeek); 
    $adjacentTime = ($time - $lastTime === 1); 
    if (!$sameWeek || ($sameWeek && !$adjacentTime)) { 

    if(!$sameWeek){//Time 
    $Days[] = $TimesReq[$i + 1]; 
      $StartTime[] = $TimesReq[$i]; 
      $looking = true; 
    } 
    if($sameWeek && !$adjacentTime){ 
    } 
    if($looking && !$adjacentTime){ 
     $EndTime[] = $TimesReq[$i]; 
     $looking = false;   
    } 
//Week  

     $sessions += 1; 
    } 
} 
+1

數據連續4周應該發生什麼?如果這被認爲是2次會議,或者代碼是否應該認識到要求(只連續3次會議)被破壞? – ghbarratt 2012-02-23 06:13:27

+0

預先驗證將意味着這不會發生。抱歉應該更具體。最多連續3次,直到休息。 – user1096685 2012-02-23 10:01:55

+0

你說甚至索引(在你的例子中爲0和2)代表幾周,但後來表明9 + 10會是同一個會話(所以在你的例子中只有一個會話),但如果他們是星期不會他們是單獨的會議? (第9周時間= 1,第10周時間= 1)。還是我完全困惑?此外,你提到幾天,但沒有關於天的數據。天/星期可以互換使用嗎? – 2012-02-23 12:06:50

回答

1

如果要在所述數據,其中每個會話由空格分隔(或者是不連續的時間,或一個單獨的天表示會話的單一總數)。我認爲這個功能會給你你的結果:

function countSessions($data) 
{ 
    if (count($data) % 2 !== 0) throw new InvalidArgumentException(); 

    $sessions = 0; 
    for ($i = 0; $i < count($data); $i += 2) { 
     $time = $data[$i]; 
     $week = $data[$i + 1]; 

     if (!isset($data[$i - 2])) { 
      // First element has to be a new session 
      $sessions += 1; 
      continue; 
     } 

     $lastTime = $data[$i - 2]; 
     $lastWeek = $data[$i - 1]; 

     $sameWeek = ($week === $lastWeek); 
     $adjacentTime = ($time - $lastTime === 1); 
     if (!$sameWeek || ($sameWeek && !$adjacentTime)) { 
      $sessions += 1; 
     } 
    } 

    return $sessions; 
} 

$totalSessions = countSessions(array(
    9, 1, 
    10, 1, 
)); 

這當然假設數據是排序的。如果不是,則需要先對其進行排序。這是一個替代實現,其中包含對未排序數據的支持。

function countSessions($data) 
{ 
    if (count($data) % 2 !== 0) throw new InvalidArgumentException(); 

    $slots = array(); 
    foreach ($data as $i => $value) { 
     if ($i % 2 === 0) $slots[$i/2]['time'] = $value; 
     else $slots[$i/2]['week'] = $value; 
    } 

    usort($slots, function($a, $b) { 
     if ($a['week'] == $b['week']) { 
      if ($a['time'] == $b['time']) return 0; 
      return ($a['time'] < $b['time']) ? -1 : 1; 
     } else { 
      return ($a['week'] < $b['week']) ? -1 : 1; 
     } 
    }); 

    $sessions = 0; 
    for ($i = 0; $i < count($slots); $i++) { 
     if (!isset($slots[$i - 1])) { // First element has to be a new session 
      $sessions += 1; 
      continue; 
     } 

     $sameWeek = ($slots[$i - 1]['week'] === $slots[$i]['week']); 
     $adjacentTime = ($slots[$i]['time'] - $slots[$i - 1]['time'] === 1); 
     if (!$sameWeek || ($sameWeek && !$adjacentTime)) { 
      $sessions += 1; 
     } 
    } 

    return $sessions; 
} 
+0

謝謝你。哪個比我的代碼更好,但是它的基本問題與我的代碼相同。其中,我從來沒有真正考慮過你的答案。數據可能無法排序。 – user1096685 2012-02-23 13:32:19

+0

如果存在未分類數據的可能性,我認爲最好的/最簡單的解決方案是首先對其進行排序。顯然保持時間/星期附加。這可能比試圖一次跟蹤所有會話更容易。 – 2012-02-23 13:38:08

+0

好點。你的功能在我的腦海中很容易跟隨,因此我現在可以實現這種排序並且運行時沒有什麼問題。非常感謝。 – user1096685 2012-02-23 13:47:31

0

這是我在解決你的問題的小小嚐試。但願我知道你想什麼:

$TimesReq = array(9,4,11,4,13,4,8,4,7,2,12,4,16,4,18,4,20,4,17,4); 

// First just create weeks with all times lumped together 
$weeks = array(); 
for($tri=0; $tri<count($TimesReq); $tri+=2){ 
    $time = $TimesReq[$tri]; 
    $week = $TimesReq[$tri+1]; 

    $match_found = false; 
    foreach($weeks as $wi=>&$w){ 
    if($wi==$week){ 
     $w[0] = array_merge($w[0], array($time)); 
     $match_found = true; 
     break; 
    } 
    } 
    if(!$match_found) $weeks[$week][] = array($time); 
} 

// Now order the times in the sessions in the weeks 
foreach($weeks as &$w){ 
    foreach($w as &$s) sort($s); 
} 

// Now break up sessions by gaps/breaks 
$breaking = true; 
while($breaking){ 
    $breaking = false; 
    foreach($weeks as &$w){ 
    foreach($w as &$s){ 
     foreach($s as $ti=>&$t){ 
     if($ti>0 && $t!=$s[$ti-1]+1){ 
      // A break was found 
      $new_times = array_splice($s, $ti); 
      $s = array_splice($s, 0, $ti); 
      $w[] = $new_times; 
      $breaking = true; 
      break; 
     } 
     } 
    } 
    } 
} 

//print_r($weeks); 

foreach($weeks as $wi=>&$w){ 
    echo 'Week '.$wi.' has '.count($w)." session(s):\n"; 
    foreach($w as $si=>&$s) 
    { 
    echo "\tSession ".($si+1).":\n"; 
    echo "\t\tStart Time: ".$s[0]."\n"; 
    echo "\t\tEnd Time: ".((int)($s[count($s)-1])+1)."\n"; 
    } 
} 

鑑於$TimesReq = array(9,4,11,4,13,4,8,4,7,2,12,4,16,4,18,4,20,4,17,4);的代碼將產生作爲輸出:

Week 4 has 4 session(s): 
    Session 1: 
     Start Time: 8 
     End Time: 10 
    Session 2: 
     Start Time: 11 
     End Time: 14 
    Session 3: 
     Start Time: 16 
     End Time: 19 
    Session 4: 
     Start Time: 20 
     End Time: 21 
Week 2 has 1 session(s): 
    Session 1: 
     Start Time: 7 
     End Time: 8 

希望有所幫助。