2013-04-30 15 views
5

Mam listę przedmiotów pracy. Każdy element pracy ma czas rozpoczęcia i zakończenia.Otrzymuj przerwy z listy czasów

Więc w zasadzie wygląda to tak:

List<Work> works = new List<Work>(); 
works.Add(new Work(
    new DateTime(2013, 4, 30, 9, 0, 0), 
    new DateTime(2013, 4, 30, 11, 0, 0)); 

Teraz chcę uzyskać całkowity czas, który został opracowany. Ponownie, w zasadzie jest to łatwe:

09:00-11:00 => 2 hours 
13:00-17:00 => 4 hours 
---- 
06:00 hours 

To tylko suma.

Ale teraz staje się trudne: jak mogę obliczyć tę sumę, jeśli chcę wyodrębnić czasy równoległe?

przykład

09:00-11:00 => 2 hours 
10:00-11:30 => 1.5 hours 
13:00-17:00 => 4 hours 
---- 
06:30 hours 

6,5 godziny, lecz suma wynosi 7,5 godziny. Fakt, że dwa elementy pracy są odwzorowane na czas między godziną 10 a 11, robi różnicę.

W jaki sposób mogę rozwiązać ten problem dla dowolnej liczby elementów pracy, które mogą się nakładać na siebie w praktycznie każdy możliwy sposób (otoczenie, początek nakładania się, nakładanie się końcówek, w tym)?

+0

Czy ustawione są określone interwały (na przykład 0,5 godziny)?Jeśli tak, prostym sposobem byłoby sprawdzenie co półgodzinnego czasu pracy dla elementu roboczego wokół niego i po prostu je wszystkie dodać. –

+0

Niestety nie, czasy są całkowicie arbitralne i mogą wynosić od kilku sekund do kilku dni. –

+1

Rozwiązałem go teraz za pomocą tej biblioteki: Łatwo, prosto i po prostu działa :-) –

Odpowiedz

5

Utwórz pary (czas, wartość), gdzie wartość wynosi +1 dla początku pracy i -1 dla końca. Następnie posortuj pary według daty. Iterując listę, którą masz, możesz obliczyć sumę wartości - kiedy jest pozytywna, praca jest "kontynuowana". Podczas iteracji zaznacz momenty, w których suma wartości wynosi od 0 do pozytywu i od dodatniej do 0. Otrzymasz rozłączne interwały.

przykład:

11 - 13 12 - 16 15 - 17 18 - 19

daje (11, 1), (12, 1) (13 1) (15, 1) (16, -1) (17, -1) (18, 1) (19, -1)

suma idzie (11, 1) (12, 2) (13 1) (15 , 2) (16, 1) (17, 0) (18, 1) (19, 0),

, więc okresami rozłącznymi są (11, 17) i (18, 19)

+2

Przykładowy kod: http://pastebin.com/KnhRwrsX Jeśli chcesz, możesz edytować odpowiedź. –

+0

Zaimplementowałem to i działa idealnie :-) Dzięki za podpowiedź! –

+0

Dzięki za próbkę, widziałem to za późno, ale teraz porównuję twoje rozwiązanie z kopalni i wykorzystam to, co najlepsze :-)) –

2

Hmm, kiedyś rozwiązałem podobny problem (nie z czasami, ale z nakładającymi się zakresami). Rozwiązanie zastosowałem była dość prosta:

  1. Uporządkuj elementy w kolejności rosnącej
  2. Począwszy od pierwszego elementu, sprawdzić, czy pokrywa się z kolejnego elementu
  3. Jeśli to jest - przetworzenie elementów, sekcję ekstrakt nakładające jako nowego elementu , modyfikować stare elementy do końca przed/po rozpocząć okres
  4. nakładania
  5. Włóż nowo utworzony element pomiędzy dwoma stare elementy
  6. kontynuować przetwarzanie

Powinno działać dobrze, jednak w przypadku dużej ilości danych może istnieć lepszy sposób na rozwiązanie tego problemu. To tylko najprostsze podejście (przynajmniej dla mnie). Otrzymasz listę razy bez nakładających się sekcji, więc będziesz mógł po prostu powtórzyć listę i podsumować czasy.