2011-02-06 15 views
9

para comprobar si hay superposición de dos dateranges diferentes, {Start1, End1} y {Start2, End2} estoy mirando:Comparación de rango de fecha múltiple para superposición: ¿cómo hacerlo de manera eficiente?

if ((Start1 <= End2) && (End1 >= Start2)) 
{ 
    //overlap exists 
} 

La pregunta es, lo que es una buena manera de comparar las superposiciones si tuviera digamos cinco dateranges? .

comprobando si alguno de ellos no se superpone entre sí?

Si tengo varios intervalos de fechas, ¿cómo puedo encontrar si alguno de estos rangos se superponen?

+3

¿Necesita saber si todos ellos se solapan en 1 punto o si alguno de ellos no se solapan entre sí? –

+1

Por favor, aclare su pregunta. ¿A qué te refieres con "comparar superposiciones"? –

+0

@Yuriy Faktorovich, @gaearon: Chicos, edité la pregunta. Básicamente, solo quiero saber si existe una superposición de no, si tuviera múltiples intervalos de fechas en cualquier orden. – VoodooChild

Respuesta

13

Para saber si todo se solapan

static bool Overlap(params Tuple<DateTime, DateTime>[] ranges) 
{ 
    for (int i = 0; i < ranges.Length; i++) 
    { 
     for (int j = i + 1; j < ranges.Length; j++) 
     { 
      if (!(ranges[i].Item1 <= ranges[j].Item2 && ranges[i].Item2 >= ranges[j].Item1)) 
       return false; 

     } 
    } 
    return true; 
} 

encontrar en su caso se solapan

static bool Overlap(params Tuple<DateTime, DateTime>[] ranges) 
{ 
    for (int i = 0; i < ranges.Length; i++) 
    { 
     for (int j = i + 1; j < ranges.Length; j++) 
     { 
      if (ranges[i].Item1 <= ranges[j].Item2 && ranges[i].Item2 >= ranges[j].Item1) 
       return true; 

     } 
    } 
    return false; 
} 
+0

+1: muy interesante. – VoodooChild

+0
+0

no es esto' n^2' mientras que la ordenación tendrá 'n log (n)'? – Snowbear

4

Si entiendo correctamente, quiere responder la pregunta: ¿Hay dos de estos rangos que se superponen? Ordénelos de acuerdo con su extremo izquierdo, y luego continúe mirando para ver si 1 se superpone a 2, si 2 se superpone a 3, etc. Si hay superposición, esto lo encontrará. No creo que haya ninguna forma de responder a su pregunta para una lista arbitraria de intervalos sin tomar al menos el tiempo O (n log n), que es lo que le costará ordenarlos.

Como alternativa, quizás desee responder a la pregunta: ¿Hay dos de estos rangos que no coinciden? (A primera vista, eso es lo que hace su pregunta editada, pero (1) parece algo extraño de desear y (2) su comentario anterior parece indicar que no es lo que quiere decir.) Para verificar esto, encuentre el intervalo con el extremo derecho más a la izquierda y el intervalo con el extremo izquierdo más a la derecha, y ver si se superponen. (Si dos de sus intervalos no se solapan, estos dos no lo hacen.)

+0

su primera suposición es correcta, es lo que quiero. – VoodooChild

1
DateTime h1 = historyRecord.serviceStartDate; 
    DateTime h2 = historyRecord.serviceEndDate; 
    DateTime r1 = record.serviceStartDate; 
    DateTime r2 = record.serviceEndDate; 
    if (!((h1 > r1 && h1 > r2 && h2 > r1 && h2 > r2) || 
     (h1 < r1 && h1 < r2 && h2 < r1 && h2 < r2))) 
     { 
     count += 1; 
     } 
2

Prueba esto:

private bool intersects(DateTime r1start, DateTime r1end, 
          DateTime r2start, DateTime r2end) 
    { 
     return (r1start == r2start) 
      || (r1start > r2start ? 
       r1start <= r2end : r2start <= r1end); 
    } 
0

Marque esta 01.234. en resumen:

Comprobación simple para ver si dos períodos de tiempo se superponen.

bool overlap = a.start < b.end && b.start < a.end; 

O en su código ...

bool overlap = tStartA < tEndB && tStartB < tEndA; 
Cuestiones relacionadas