我有元组列表。每个元组都是最小值和最大值。
我想检查是否在提供的列表中是否缺少任何范围或它们是否重叠。
这是定义。
List<Tuple<int, int>> sequences = new List<Tuple<int, int>>();
示例:
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);
当序列的值为:
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 gap会返回一个不应该的计数,因为它们是一个没有间隙或没有重叠的有效范围
答案 0 :(得分: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
订购。
答案 1 :(得分:1)
如果你只需要一个是或否答案,我相信以下回答问题:
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));
希望您能够轻松地“阅读”第一个查询。第二个花了我一些努力,但有效地问“是否有任何元组(除了从1开始的元组),其最低值-1未被集合中的另一个元组覆盖?”
但是,如果您的集合很大,我会在SQL中而不是在C#中执行此操作 - 感觉这是一个更自然的地方,可以提出这样的“基于集合”的问题。