2016-08-22 1 views
0

セッションの有効期限の時間とセッションのタイムアウト値のリストがあります。 セッションの開始時間から有効期限のタイムアウトを差し引くことができます。リストに日付が重複したままになる

私は2つの日付が重なっているかどうかを確認する方法を知っている:

public boolean isOverlapped(LocalDateTime start1, LocalDateTime end1, 
          LocalDateTime start2, LocalDateTime end2) { 
    return (start1.isBefore(end2) || start1.equals(end2)) 
      && (start2.isBefore(end1) || start2.equals(end2)); 
} 

が、日付のリストのためにこれを行うにはどのようには考えています。

結果私は、重複した(並行して)セッションの中で最も長いチェーンを持つリストを持っていたいと思います。 ありがとうございました!

+2

「オーバーラッピング」は、日付間の4桁の関係です。したがって、各リスト要素が1つの日付である場合、「重複する日付のみ」のリストを持つことはどういう意味ですか? –

+1

興味のある「重複」の可能な意味をすべて網羅し、入力と期待される出力を示す一連のテストデータを考案する必要があります。私はあなたが結果が欲しいものをまだ明確にしているかどうかはわかりません。 1つの可能な明白な定義は、複数の間隔のメンバーである時間のスパンを識別し、それらのスパンのうちの1つを含むすべての間隔を出力することです。しかし、それはあなたが「重なり合っている」という意味ではないかもしれません。今立つように、この質問は "あなたが求めているものが不明"と閉ざされるかもしれません。 –

+0

あなたのリストはどのように開始日と終了日を保持していますか? – Shahid

答えて

0

まず第一に、(お持ちでない場合)、これらのセッションを表す新しいクラスを作る:

class Session { 
    private LocalDateTime start; 
    private LocalDateTime end; 

    public boolean isOverlapped(Session other) { 
     return (start.isBefore(other.end) || start.equals(other.end)) 
      && (end.isAfter(other.start) || end.equals(other.start)); 
    } 
    ...  
} 

ご入力リストはSession秒のリストである必要があります。

次に、質問したことを実行するアルゴリズムを示します。それはリスト内に入れて、それがのいずれかの他の要素と重複するならば(各要素を除く)、各要素をチェックします。その場合は、それが結果リストにそれを置く:ここ

public static List<Session> filter(List<Session> in) { 
    List<Session> result = new ArrayList<>(); 

    for(Session current : in) { 
     for(Session other : in) { 
      if(current != other && current.isOverlapped(other)) { 
       result.add(current); 
       break; 
      } 
     } 
    } 

    return result; 
} 

はまた、例えばプログラムです:Ideone

結果は、他のセッションと同時だったセッションを含むリストになります。

+0

助けてくれてありがとう!たぶん問題の説明が十分ではないかもしれません。推奨アルゴリズムを使用して、他のセッションと重複しているセッションのリストを取得します。しかし、もし私が並行セッションの最長チェーンを取得したいのであれば、どうでしょうか。何か案は? – user936

+0

@ user936それは複雑さの中で一歩です。私は後でそれを調べるかもしれない。 –

+0

私はそれが正しいかどうか分かりませんが、キーとしてセッションを持つマップを作成し、重複したセッションのリストを値として使用します。私はあなたのフィルタメソッドを少し変更して使用します(結果として私は他のセッションを追加します)。だからこのようにして私はmapを持っていて、値のリストサイズでこのマップをソートし、mapから最初の要素を取得する以上のものです。 – user936

0

これはかなり古典的な問題です。時間の点で、または間隔の数で最も長いセッションを希望するかどうかは指定していませんが、どちらも同じ方法で動作します。

最初にすべてのセッションを開始時刻で並べ替えます。次に、ロジックは次のようになります。

current_chain = [] 
best_chain = [] 
for session in sessions_sorted_by_start: 
    if session doesn't overlap with any session in curent_chain: [1] 
     update best_chain if current_chain is better    [2] 
     current_chain = [] 
    current_chain.insert(session)         [3] 
update best_chain if current_chain is better      [2] 

ここでのアイデアは、現在のチェーンを維持することです。新しいセッションがチェーン内の他のセッションと重複している場合は、チェーンに追加するだけです。現在のチェーン内のセッションと重複しない場合は、現在のチェーン内の最も遠いセッションの最後から右に開始するので、他の残りのセッションは現在のチェーンのものと重複しません(開始日でソート)。つまり、現在のチェーンはこれまでと同じ長さであるため、これまでのベストセラーチェーン([2])よりも優れているかどうかを確認してリセットすることができます。

ここで、時間的に線形にするには、一定時間内に[1]でセッションとチェーンのオーバーラップチェックを行うのがいいでしょう。これは、チェーンのために常に最も遠いセッションを維持している場合には簡単に実行されます。これを行うには、[3]で新しいセッションを挿入するときに、その最後が現在の最も遠いセッションの終わりを超えている場合は、最も遠いセッションを更新し、そうでない場合は更新しないでください。この方法では[1]で最も近いセッションとのオーバーラップをチェックするだけで、すべてのチェックを行う代わりに、その特定のチェックを一定時間にし、アルゴリズム全体をリニアにする必要があります(初期ソートを考慮していない場合もちろんO(n log n))。

関連する問題