2012-01-20 11 views
2

タプルのリストがあります。各タプルは最小値と最大値です。c#+タプルのリストの空白とオーバーラップを確認する

範囲のいずれかが欠落しているか、重複しているかどうかは、提供されたリストで確認したいと思います。

これは定義です。

List<Tuple<int, int>> sequences = new List<Tuple<int, int>>(); 

例:この場合

minrange = 1; 
maxrange = 2097152;  
sequences.Add(new Tuple<int, int>(1, 10)); 
    sequences.Add(new Tuple<int, int>(11, 20)); 
    sequences.Add(new Tuple<int, int>(21, 2097152)); 

私のvarギャップは数を返します。シーケンスの値がある場合

1. sequences.Add(new Tuple<int, int>(1, 10)); 
    sequences.Add(new Tuple<int, int>(11, 20)); 
    This is fine 

2. sequences.Add(new Tuple<int, int>(1, 10)); 
    sequences.Add(new Tuple<int, int>(13, 20)); 
    This there are gaps in the sequence 

3. sequences.Add(new Tuple<int, int>(1, 10)); 
    sequences.Add(new Tuple<int, int>(10, 20)); 
    This is an overlapping scenario 

は現在、私は

int minrange = 1; 
    int maxrange = 20; 
    var gaps = Enumerable.Range(minrange, maxrange).Where(i => sequences.All(t => t.Item1 > i || t.Item2 < i)); 
    var overlapping = Enumerable.Range(minrange, maxrange).Where(i => sequences.Count(t => t.Item1 <= i && t.Item2 >= i) > 1); 

をしていますそれは避けるべきではないeギャップがないか重複しない有効範囲です

  1. これは正しい方法ですか?
  2. 私は間違っていますか?
+0

*ギャップ/オーバーラップがあるかどうかを知る必要がありますか、またはその数を*カウントする必要がありますか? –

+1

必要に応じて、http://en.wikipedia.org/wiki/Interval_treeなどのデータ構造が役立つ場合があります。 –

+0

@Nate:それはまさに私がコードで達成しようとしていることです:) – Vivek

答えて

1

あなただけyesまたはnoの答えが必要な場合は、私は次の質問に答えると信じて:うまくいけば

var overlaps = 
    (from s1 in sequences from s2 in sequences 
    where s1.Item2 >= s2.Item1 && s1.Item1 < s2.Item1 select s1).Any(); 

var gaps = 
    (from s1 in sequences where s1.Item1 > 1 select s1.Item1).Any(
      i => !sequences.Any(
       j => j.Item2 >= i-1&&j.Item1 < i)); 

、あなたは合理的に簡単に最初のクエリを「読む」ことができます。 2番目は少し努力しましたが、「1から始まるタプル以外のタプルは最低値-1で、コレクション内の別のタプルで覆われていないタプルはありますか」と効果的に質問します。

しかし、あなたのセットが大きいなら、私はC#ではなくSQLでこれをやっています - それは "セットベースの"質問をするより自然な場所だと感じています。

1

私はまだそれをテストしていないが、あなたは次の操作を行うことができ、ギャップを見つけるために:

int lastMax = sequences[0].Item2; 
var gaps = sequences.Skip(1).Where(item => 
    { 
     bool res = lastMax + 1 < item.Item1; 
     lastMax = item.Item2; 
     return res; 
    }); 

、重複アイテムを見つけるために:

int lastMax = sequences[0].Item2; 
var overlaps = sequences.Skip(1).Where(item => 
    { 
     bool res = lastMax >= item.Item1; 
     lastMax = item.Item2; 
     return res; 
    }); 

両方の例があることを前提としあなたのリストはすでにItem1で注文されています。

関連する問題