【发布时间】:2010-04-23 11:35:21
【问题描述】:
示例:如果我添加一个范围 {1,10} 和另一个范围{15,20} 我应该会收到一条消息,说缺少 11 到 14 的范围。
【问题讨论】:
-
这是作业吗?到目前为止,您尝试过什么?
-
这段代码非常需要 cmets 和一些更好的变量名
示例:如果我添加一个范围 {1,10} 和另一个范围{15,20} 我应该会收到一条消息,说缺少 11 到 14 的范围。
【问题讨论】:
你是如何添加范围的?
如果按顺序添加范围,您可以只保留最后一个范围的结尾并与您添加的范围的开头进行比较。
如果您可以按任意顺序添加范围,则必须在添加所有范围时进行检查。对范围开头的范围进行排序,然后循环遍历范围并将范围的结尾与下一个范围的开头进行比较。
第二种情况的例子。首先是一个保存范围的类:
public class Range {
public int From { get; private set; }
public int To { get; private set; }
public Range(int from, int to) {
From = from;
To = to;
}
}
创建范围列表:
List<Range> ranges = new List<Range>();
ranges.Add(new Range(15, 20));
ranges.Add(new Range(1, 10));
测试范围:
ranges = ranges.OrderBy(r => r.From).ToList();
for (int i = 1; i < ranges.Count; i++) {
int to = ranges[i - 1].To;
int from = ranges[i].From;
int diff = to.CompareTo(from - 1);
if (diff < 0) {
Response.Write("Range from " + (to + 1).ToString() + " to " + (from - 1).ToString() + " is missing<br/>");
} else if (diff > 0) {
Response.Write("Range ending at " + to.ToString() + " overlaps range starting at " + from.ToString() + "<br/>");
}
}
注意:代码检查范围内的间隙和重叠范围。如果重叠范围不是问题,只需删除检查diff > 0 的部分即可。
【讨论】:
不清楚您的代码试图做什么,但这是您可能应该采取的基本方法:
Start 和End 的Range 类型
Start 属性对集合排序(可能使用Enumerable.OrderBy)。Enumerable.Zip 压缩集合,自身偏移一)并检查它们是否相邻。如果不是,则生成缺失的范围。例如
var ordered = ranges.OrderBy(range => range.Start);
var pairs = ordered.Zip(ordered.Skip(1), (a, b) => new { a, b });
var missing = from pair in pairs
where pair.a.End + 1 < pair.b.Start
select new Range(pair.a.End + 1, pair.b.Start - 1);
【讨论】:
输入容错解决方案和用于构建它的programming Kata。
public class Range
{
public int End;
public int Start;
public Range(int start, int end)
{
Start = start;
End = end;
}
}
public class RangeGapFinder
{
public Range FindGap(Range range1, Range range2)
{
if (range1 == null)
{
throw new ArgumentNullException("range1", "range1 cannot be null");
}
if (range2 == null)
{
throw new ArgumentNullException("range2", "range2 cannot be null");
}
if (range2.Start < range1.Start)
{
return FindGap(range2, range1);
}
if (range1.End < range1.Start)
{
range1 = new Range(range1.End, range1.Start);
}
if (range2.End < range2.Start)
{
range2 = new Range(range2.End, range2.Start);
}
if (range1.End + 1 >= range2.Start)
{
return null; // no gap
}
return new Range(range1.End + 1, range2.Start - 1);
}
}
【讨论】: