11

2つの異なる日付範囲の重複をチェックするには、{Start1, End1}次の{Start2, End2}ことをチェックします。

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

問題は、 5つの日付範囲を考えた場合、重複を比較するための良い方法は何ですか?

それらのいずれかが互いに重複していないかどうかを確認しますか?

複数の日付範囲がある場合、これらの範囲のいずれかが重複しているかどうかを確認するにはどうすればよいですか?

4

6 に答える 6

15

すべてが重複しているかどうかを確認するには

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;
}

重複しているかどうかを確認する

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;
}
于 2011-02-06T00:57:31.187 に答える
6

私が正しく理解している場合、あなたは質問に答えたいと思います:これらの範囲の2つが重複していますか?それらを左端に従って並べ替えてから、1が2に重なっているのか、2が3に重なっているのかなどを確認します。重なっている場合は、これで検出されます。少なくともO(n log n)時間をかけずに、任意の間隔のリストについて質問に答える方法はないと思います。これは、それらを並べ替えるのにかかる費用です。

あるいは、次の質問に答えたいと思うかもしれません。重複しないこれらの範囲の2つはありますか?(一見すると、編集した質問が尋ねていることですが、(1)それは奇妙なことのように思われ、(2)上記のコメントは、それがあなたの意図したものではないことを示しているようです。)これを確認するには、左端の間隔と右端の左端の間隔を確認し、それらが重なっているかどうかを確認します。(間隔のいずれか2つが重ならない場合、これら2つは重なりません。)

于 2011-02-06T00:47:07.260 に答える
2

これを試して:

    private bool intersects(DateTime r1start, DateTime r1end, 
                            DateTime r2start, DateTime r2end)
    {
        return (r1start == r2start) 
            || (r1start > r2start ? 
                r1start <= r2end : r2start <= r1end);
    }
于 2011-08-04T14:10:32.423 に答える
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;
       }
于 2011-05-24T19:56:30.730 に答える
1

このアルゴリズムをチェックして、重複する期間 を簡単に検出します。

2つの期間が重なっているかどうかを確認する簡単なチェック。

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

またはあなたのコードで...

bool overlap = tStartA < tEndB && tStartB < tEndA;
于 2017-08-23T10:15:56.557 に答える
0

ガレスの答えを補完するために。より複雑なタイプのオーバーラップチェックを間隔で実行する必要がある人のために、間隔ツリーと呼ばれる優れたデータ構造があります。

https://en.wikipedia.org/wiki/Interval_tree

間隔を保持するツリーデータ構造。具体的には、任意の間隔またはポイントと重複するすべての間隔を効率的に見つけることができます。

このjavascript実装からの例

let tree = new IntervalTree();

let intervals = [[6,8],[1,4],[5,12],[1,1],[5,7]];

// Insert interval as a key and string "val0", "val1" etc. as a value 
for (let i=0; i < intervals.length; i++) {
    tree.insert(intervals[i],"val"+i);
}

// Get array of keys sorted in ascendant order
let sorted_intervals = tree.keys;              //  expected array [[1,1],[1,4],[5,7],[5,12],[6,8]]

// Search items which keys intersect with given interval, and return array of values
let values_in_range = tree.search([2,3])  //  expected array ['val1']
于 2020-05-15T03:34:29.830 に答える