2014-09-27 71 views
0

我正在嘗試查找反向交集,以查看兩個團隊是否可以彼此玩,但很難搞清楚準確的代碼。計算包含範圍的兩個列表之間的交集/截距

對下列範圍進行重新認定的類將包含兩個屬性,一個開始時間和結束時間,可以是日期時間或時間跨度。每個團隊都可以有這些列表。時間跨度屬性會下降到下午2點21分有效。

團隊1無法在列出的這兩個時間之間進行比賽,因此他們只能在上午10:00至下午5:00進行比賽。儘管如此我們存儲排除。

第二隊可以在下午8:00到下午12:00進行比賽。

意義隊1和隊2可以在10-12之間進行比賽。有沒有一種很好的方法來計算出代碼?

隊1個

List<Restriction> 
    Restriction 
      StartTime: 8:00 AM 
      EndTime: 10:00 AM 
    Restriction 
      StartTime: 5:00 PM 
      EndTime: 9:00 PM 

隊2

List<Restriction> 
    Restriction 
      StartTime: 12:00 PM 
      EndTime: 9:00 PM 
+0

對不起任何澄清,我很困惑與時間符號。 – ziya 2014-09-27 01:16:39

+0

只需在這裏大聲輸入,但我想你可以將當天的所有時間都轉換爲可播放時間爲1的字節數組中的位,然後在團隊之間進行AND操作。搖出什麼是他們可以相互對戰的時刻。 – Crowcoder 2014-09-27 01:36:46

+0

如果您將時間轉換爲可以播放(甚至是暫時)的時間,然後將其轉換爲可用時間集合,則它將成爲交叉點而不是反向交叉點。 – 2014-09-27 01:52:42

回答

1

根據每次是開始還是結束時間,對所有開始和結束時間進行排列,包括+1或-1。

對於您所設定的時間,這給你:

[(08:00, +1), (10:00, -1), (17:00, +1), (21:00, -1), (12:00, +1), (21:00, -1)] 

排序他們:

[(08:00, +1), (10:00, -1), (12:00, +1), (17:00, +1), (21:00, -1), (21:00, -1)] 

執行加的運行總和,並減去1的:

[(08:00, 1), (10:00, 0), (12:00, 1), (17:00, 2), (21:00, 1), (21:00, 0)] 

的運行總數是當時正忙於開始的隊(0,1或2)的數量。所以現在被標記爲0的時間是兩隊都是免費的(這裏是10:00和21:00)的開始時間。陣列中的下一次是空閒時間的結束。這給出了兩隊都是免費的時間段,其中包括開始和結束時的時間段(無效至08:00),(10:00至12:00)和(21:00至+無限)。

+0

有趣。我會試試這個。看起來正是我所需要的,如果是這樣的話,我會永遠不會想到。你是怎麼想出來的? – 2014-09-27 12:37:20

+0

你會如何處理10 AM-3PM和12-9兩支球隊?我需要包含無限-10嗎? – 2014-09-28 16:02:31

0

之後可能會有幫助,你所談論的時間範圍內,當一支球隊可以玩,也與其他團隊的交集。目前正如我從例子中看到的,最小單位是1小時,比如8-9,9-10。總時間似乎在上午8點到下午9點之間,可以是任何事情。如果我的理解是正確的。

現在形成像8-9,9-10,10-11這樣的最小單位範圍,並用於像字典這樣的數據結構來更新布爾真/假,一個團隊是否可以玩,現在你必須選擇所有的範圍都是真實的,那就是交叉點或播放範圍。

數據結構可能是 - Dictionary<Tuple<int,int>, bool>

我不知道進一步的複雜性,但您可以使用類似的邏輯,包括周,月,年的天太。

我不太清楚你的總體描述,如果你沒有別的選擇,並且你只想在List中做並且沒有轉換,那麼就需要考慮另一種算法。

+0

如果我告訴過你可能是分鐘,下午2點25分,那會更復雜嗎? – 2014-09-27 02:10:30

+0

@Mike Flynn,是的,但是最終這個時間會落在一個範圍內,我的理解是隊伍允許在一個範圍/插槽中打,而不是在另一個範圍/插槽中打,我們可以將一個單位降到一個分鐘或秒,無論適合的業務邏輯 – 2014-09-27 02:28:37

+0

我建議的解決方案是與上面建議的位邏輯相同,您已經喜歡,無論您想獲得位值1還是真實值都沒關係,但它應該是相同的參加比賽的球隊 – 2014-09-27 02:36:20

0

這裏是代碼的工作版本,基於問題提供的細節,重要的細節是:

  1. 時隙粒度在幾分鐘內,它甚至可以在幾秒鐘內。
  2. 它以24小時格式打印出最終答案。
  3. 時間從0小時 - 24小時開始,因此打印時間爲0-8,10-12和21-24。需要額外的邏輯來消除像0-8,21-24這樣的小時,如果它們被定義爲不尋常的小時
  4. 代碼不遵循所有的編碼標準,它只是照顧預期的邏輯和算法中建議的算法最後的答案。
  5. 請讓知道的情況下,你需要相關實施

    using System; 
    using System.Collections.Generic; 
    
    public class PlayTimeTest 
    { 
    public static void Main(string[] args) 
    { 
        IntersectTime teamIntersectingTime = new IntersectTime(); 
        teamIntersectingTime.CreateTeams(); 
    
        Dictionary<Tuple<int, int>, bool> validTimeSlot = teamIntersectingTime.FindTimeSlot(); 
    
        teamIntersectingTime.PlayTimeDisplay(validTimeSlot); 
        Console.ReadLine(); 
    } 
    } 
    
    
    internal class IntersectTime 
    { 
        Team teamA { get; set; } 
        Team teamB { get; set; } 
    
    public void CreateTeams() 
    { 
        TimeRestriction A1 = new TimeRestriction(); 
        A1.startTime = 8; 
        A1.endTime = 10; 
    
        TimeRestriction A2 = new TimeRestriction(); 
        A2.startTime = 17; 
        A2.endTime = 21; 
    
        List<TimeRestriction> teamARestrictions = new List<TimeRestriction>(); 
        teamARestrictions.Add(A1); 
        teamARestrictions.Add(A2); 
    
        teamA = new Team(teamARestrictions); 
        teamA.CreateSlotDictionary(); 
    
        TimeRestriction B1 = new TimeRestriction(); 
        B1.startTime = 12; 
        B1.endTime = 21; 
    
    
        List<TimeRestriction> teamBRestrictions = new List<TimeRestriction>(); 
        teamBRestrictions.Add(B1);   
    
        teamB = new Team(teamBRestrictions); 
        teamB.CreateSlotDictionary(); 
    } 
    
    public Dictionary<Tuple<int,int>,bool> FindTimeSlot() 
    { 
        Dictionary<Tuple<int, int>, bool> returnTimeSlot = new Dictionary<Tuple<int, int>, bool>(); 
    
        foreach(KeyValuePair<Tuple<int, int>, bool> currentIndividualSlot in teamA.AvailableSlot) 
        { 
         if (currentIndividualSlot.Value == true && teamB.AvailableSlot[currentIndividualSlot.Key] == true) 
          returnTimeSlot.Add(currentIndividualSlot.Key, currentIndividualSlot.Value); 
        } 
    
        return (returnTimeSlot); 
    } 
    
    public void PlayTimeDisplay(Dictionary<Tuple<int, int>, bool> validTimeSlot) 
    { 
        int startValidTime = 0; 
    
        int endValidTime = 0; 
    
        int testCounter = 0; 
    
        KeyValuePair<Tuple<int, int>, bool> playBeginTime = new KeyValuePair<Tuple<int, int>, bool>(); 
        KeyValuePair<Tuple<int, int>, bool> lastPlayTime = new KeyValuePair<Tuple<int, int>, bool>(); 
    
        foreach(KeyValuePair<Tuple<int, int>, bool> playTime in validTimeSlot) 
        { 
         lastPlayTime = playTime; 
         startValidTime = playTime.Key.Item1; 
    
         if(testCounter == 0) 
          playBeginTime = playTime; 
    
         if(endValidTime !=0 && (startValidTime != endValidTime)) 
         { 
          int beginTimeInMinutes = playBeginTime.Key.Item1; 
          int endTimeInMinutes = endValidTime; 
    
          int timeResult; 
    
          int beginTimeInHours = Math.DivRem(beginTimeInMinutes, 60, out timeResult); 
          int endTimeInHours = Math.DivRem(endTimeInMinutes, 60, out timeResult); 
    
          Console.WriteLine("Teams play between :: " + beginTimeInHours + " - " + endTimeInHours + "hours"); 
          testCounter = 0; 
          endValidTime = playTime.Key.Item2; 
         } 
         else 
         { 
          endValidTime = playTime.Key.Item2; 
          testCounter ++; 
         } 
        } 
    
        if ((playBeginTime.Key.Item1 != lastPlayTime.Key.Item1) && (playBeginTime.Key.Item2 != lastPlayTime.Key.Item2)) 
        { 
         int beginTimeInMinutes = playBeginTime.Key.Item1; 
         int endTimeInMinutes = lastPlayTime.Key.Item2; 
    
         int timeResult; 
    
         int beginTimeInHours = Math.DivRem(beginTimeInMinutes, 60, out timeResult); 
         int endTimeInHours = Math.DivRem(endTimeInMinutes, 60, out timeResult); 
    
         Console.WriteLine("Teams play between :: " + beginTimeInHours + " - " + endTimeInHours + "hours"); 
        } 
    } 
    } 
    
    
    internal class TimeRestriction 
    { 
    // 24 hour time slot 12 AM = 0 
    public int startTime { get; set; } 
    
    // 24 hour time slot // 12 PM = 12, 9 PM = 21 
    public int endTime { get; set; }  
    
    public int ConvertToMinutes(int hourTimeSlot) 
    { 
        return (hourTimeSlot * 60); 
    } 
    } 
    
    
    internal class Team 
    { 
        public Team(List<TimeRestriction> teamTimeRestrictions) 
        { 
        TeamTimeRestrictions = teamTimeRestrictions; 
        AvailableSlot = new Dictionary<Tuple<int, int>, bool>(); 
        } 
    
    public Dictionary<Tuple<int, int>, bool> AvailableSlot { get; set; } 
    
    public List<TimeRestriction> TeamTimeRestrictions { get; set; } 
    
    
    public void CreateSlotDictionary() 
    { 
        int beginTime = 0; 
        int endTime = 1440; 
    
        for (int slotTime = beginTime; slotTime < endTime; slotTime++) 
        { 
         Tuple<int, int> timeTuple = new Tuple<int, int>(slotTime, slotTime + 1); 
         AvailableSlot.Add(timeTuple, true); 
        } 
    
        // Apply Restrictions 
        foreach(TimeRestriction currentRestriction in TeamTimeRestrictions) 
        { 
         for(int currentTime = currentRestriction.ConvertToMinutes(currentRestriction.startTime); 
          currentTime < currentRestriction.ConvertToMinutes(currentRestriction.endTime); currentTime++) 
         { 
          Tuple<int, int> restrictionTimeTuple = new Tuple<int, int>(currentTime, currentTime + 1); 
          AvailableSlot[restrictionTimeTuple] = false; 
         } 
        } 
    
    } 
    } 
    
+0

@Mike Flynn你有沒有機會嘗試解決方案,它是否讓你更接近你想要做的事情。 – 2014-09-28 08:33:40

相關問題