Portál AbcLinuxu, 10. května 2025 21:37
Řešení dotazu:
Návrh, mohlo by to fungovat...
Převedl bych intervaly na 2 jakési "události" typu začátek(B) a konec(E). Ještě je třeba mít referenci na samotný interval.
Vše naskládat do pole a setřídit, takže z toho vyjde něco takového: (pro správnost třeba třídit i podle např ID události, zde je to abeceda A—E)
Vytvořit prázdný zásobník (nějaké pole)
Při iteraci každá událost začátek(B:) v poli způsobí uložení na zásobník. Pokud byl zásobník neprázdný, existuje zde průnik.
Kažká událost konec(E:) v poli způsoví odstranění prvku ze zásobníku; všechny intervaly na zásobníku se před vyzvednutím překrývají
Doufám, že je to alespoň trochu k pochopení Důležité je pochopit že i když je to jeden interval jsou to v podstatě dvě skalární tříditelné hodnoty...
#!/bin/bash A=(1000 1500) B=(1200 1700) C=(1600 2000) for x in A B C; do for y in A B C; do xmin=${!x} xmax=$(eval echo '$'{$x[1]}) ymin=${!y} ymax=$(eval echo '$'{$y[1]}) if [[ $ymin -gt $xmin && $ymin -lt $xmax ]]; then if [[ $imax -gt $ymax ]]; then echo "$x$y $ymin $ymax" else echo "$x$y $ymin $xmax" fi fi done doneVýstup:
AB 1200 1500 BC 1600 1700
<?php $A=array(1000,1500); $B=array(1200,1700); $B=array(1600,2000); $AB=array(max($A[0],$B[0]),min($A[1],$B[1])); $BC=array(max($B[0],$C[0]),min($B[1],$C[1])); ?>
$classes = array( array( 'name' => 'A', 'day' => 'Monday', 'start'=> '08:00AM', 'end' => '11:00AM', ), array( 'name' => 'B', 'day' => 'Monday', 'start'=> '10:00AM', 'end' => '11:30AM', ), array( 'name' => 'C', 'day' => 'Monday', 'start'=> '12:00PM', 'end' => '04:00PM', ), array( 'name' => 'D', 'day' => 'Monday', 'start'=> '03:00PM', 'end' => '06:00PM', ), array( 'name' => 'E', 'day' => 'Monday', 'start'=> '10:00AM', 'end' => '10:30AM', ), array( 'name' => 'F', 'day' => 'Monday', 'start'=> '11:00AM', 'end' => '11:30AM', ), ); $overlap = array(); foreach ($classes as $class1) { foreach ($classes as $class2) { if ($class1['day'] != $class2['day'] || $class1 == $class2) continue; if (strtotime($class1['start']) < strtotime($class2['end']) && strtotime($class1['start']) >= strtotime($class2['start'])) { $array = array($class1['name'], $class2['name']); sort($array); if (!in_array($array, $overlap)) $overlap[] = $array; } } } print_r($overlap);to mi dá výsledok:
Array ( [0] => Array ( [0] => A [1] => B ) [1] => Array ( [0] => B [1] => E ) [2] => Array ( [0] => C [1] => D ) [3] => Array ( [0] => A [1] => E ) [4] => Array ( [0] => B [1] => F ) )teraz by stacilo nejako vyselektovať kombinácie, kde sa vyskytuje na začiatku A, t.j. AB,AE a zároveň pole s BE (druhé hodnoty poľa so začiatočným A), takže dostanem výsledok ABE. nejaký nápad na toto? potom následne nájdem spoločný min max prienik ABE a malo by to byť hotové.
SELECT * FROM rozsah;
id|name|mi|ma 1|A|1000|1500 2|B|1200|1700 3|C|1600|2000 4|D|2500|3000SELECT n,pmi,pma,pma-pmi AS pm FROM (SELECT r1.name||r2.name AS n, max(r1.mi,r2.mi) AS pmi, min(r1.ma,r2.ma) AS pma FROM rozsah AS r1, rozsah AS r2 WHERE r1.id<r2.id AND pmi<=pma) ORDER BY pm DESC;
n|pmi|pma|pm AB|1200|1500|300 BC|1600|1700|100
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.