如何检查两个系列日期是否重叠并确定它出现的第一个日期?

时间:2016-02-14 20:17:04

标签: performance date comparison range

如何检查两个系列的日期是否重叠并确定它出现的第一个日期?

想象一下,我在Google日历中创建了两个事件。其中一个在Date1中,每隔X天重复一次;另一个在Date2中,每隔Y天重复一次。

确定两个系列是否会在某一天重叠并找到它会发生的第一个日期的最佳算法是什么?

示例1:

Date1 = Feb-15, 2016
X = 14 (repeat every 14 days)
Date2 = Feb-22, 2016
Y = 21 (repeat every 21 days)
Result: first overlap on Mar-14, 2016

enter image description here

示例2:

Date1 = Feb-15, 2016
X = 14 (repeat every 14 days)
Date2 = Feb-22, 2016
Y = 28 (repeat every 28 days)
Result: will never overlap

1 个答案:

答案 0 :(得分:2)

让我们定义2系列之间的数学关系。 首先定义一些变量:

  
      
  • c - 这是开始日期之间的初始偏移量(Date2 - Date1)
  •   
  • S 1 - 这是"步长" (重复)Date1。
  •   
  • S 2 - 这是"步长" (重复)Date2。
  •   
  • i - 重叠点系列1的重复次数。
  •   
  • j - 重叠点处系列2的重复次数。
  •   

我们可以说当系列重叠时,存在一些 i j ∈ℤ(整数),这样:

  

i * S 1 = c + j * S 2 (然后)
   i =(c + j * S 2 )/ S 1

要查找 j (然后通过 c + j * S 2 重叠点),我们可以使用以下算法:< / p>

if c % S1 is 0 then return 0
else  
  let j = 1
  while (S2 * j) % S1 != c
    if (c + S2 * j) % S1 == 0 then return j
    j = j + 1
  loop
  return -1 (not found)

如果算法返回-1,则没有重叠。否则会发现重叠。

你可以在这里尝试一下:

&#13;
&#13;
$('#find').click(function() {
  var c = +$('#C').val();
  var S1 = +$('#S1').val();
  var S2 = +$('#S2').val();

  var j = findOverlap(c, S1, S2);
  if(j === -1) {
    $('#result').text('No overlap!');
    return;
  }

  $('#result').text('Overlap found at ' + (c + S2 * j));
});

function findOverlap(c, S1, S2) {
  if(c % S1 === 0) {
    return 0;
  }

  var j = 1;
  while((S2 * j) % S1 > 0) {
    if((c + S2 * j) % S1 === 0) {
      return j;
    }
    j++;
  }
  return -1;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
C: <input type="text" id="C" /><br/>
S1: <input type="text" id="S1" /><br/>
S2: <input type="text" id="S2" /><br/>
<button id="find">Find!</button><span id="result"></span>
&#13;
&#13;
&#13;

我认为这也是一种纯粹的数学方法来提出这个问题,但我认为它会涉及LCM算法的变体,这需要类似的迭代步骤。