2

我的代码中有以下结构:

class Interval {
    public $start, $end;
}

class Period {
    public $interval, $period;
}

它们分别代表一个简单的和重复的区间。例如:

**** // This is a simple interval [0, 4].
****__****__**** // This is "repeating interval" with period = 2 (each underline means pause between intervals)

所以 period 是一组无限的区间。它们之间的“距离”(或暂停)是恒定的。

我需要一个接受任意间隔和周期的函数,并说明该间隔是否在周期内。“内部”表示给定区间在周期内的任何区间内。

function interval_inside_period(Interval $interval, Period $period) {
  return is_inside ? true : false;
}

$period = new Period(new Interval(0, 4), 10); 
// The first 3 intervals in this Period are [0, 4], [14, 18] and [28, 32]
// Like: ****__________****__________****
interval_inside_period(new Interval(15, 16), $period); // === true, is inside [14, 18]
interval_inside_period(new Interval(29, 32), $period); // === true, is inside [28, 32]
interval_inside_period(new Interval( 3,  5), $period); // === false, overlaps but is not inside
interval_inside_period(new Interval(17, 29), $period); // === false, overlaps but is not inside
interval_inside_period(new Interval(11, 12), $period); // === false
interval_inside_period(new Interval(20, 27), $period); // === false

问题是由于缺乏数学经验,我不知道如何实现这样的功能。我考虑过波函数,特别是矩形周期函数,但我不知道如何用这种函数来描述周期。

具有相同长度和周期性的简单周期可以用方波函数来描述:

$square_period = new Period(new Interval(0, 2), 2);
// __**__**__**__**
// This function describes such Period.
function is_square_period($n) {
    return ($n >= 0 && ($n / 2) % 2) == 0 ? 1 : 0;
}

这种方法提供了查找是否有任何整数 $n 位于 Period 内的机会。但我不知道这是否可以用来解决问题。

有任何想法吗?提前致谢。

4

1 回答 1

1

让我们看看......两个连续间隔之间的偏移量是$start + $end + $period。因此,区间的起点kk * ($start + $end + $period) + $start。通过x将给定的 Interval ( new Interval(x, y)) 除以$start + $end + $period我们可以计算出我们的k:

// this is should be integer division...
$k = ($interval->start - $period->interval->start)
    / ($period->interval->start + $period->interval->end + $period->period);

现在我们可以计算区间的边界k并检查给定的区间是否在其中。

$kStart = $k * (
        $period->interval->start + $period->interval->end + $period->period
    ) + $period->interval->start;
$kEnd = $kStart + ($period->interval->end - $period->interval->start);

return $kStart <= $interval->start && interval->end <= $kEnd;

这会产生以下内容,其中包含您问题的期间和第一个间隔:

$k = (15 - 0) / (0 + 4 + 10) = 15 / 14 = 1
$kStart = 1 * (0 + 4 + 10) + 0 = 1 * 14 + 0 = 14
$kEnd = 14 + (4 - 0) = 18

return (14 <= 15 && 16 <= 18) // true

剩余间隔的值为:

iStart | iEnd | k | kStart | kEnd | result
-------+------+---+--------+------+-------
    29 |   32 | 2 |     28 |   32 | true
     3 |    5 | 0 |      0 |    4 | false
    17 |   29 | 1 |     14 |   18 | false
    11 |   12 | 0 |      0 |    4 | false
    20 |   27 | 1 |     14 |   18 | false
于 2013-08-15T12:01:12.593 回答