How get range of numbers [duplicate]
I have a interval of number [1, 20].
I want a method which returns me range of number available if I decide to ban range [15, 18]. My method should return me a list containing [1,15] and [18, 20]
Range object could looks like something like that
public class Range
{
int Start {get;set;}
int End {get;set;}
}
Any help would be appreciated.
What about this?
IEnumerable<int> range = Enumerable.Range(1, 20);
IEnumerable<int> banned = Enumerable.Range(15, 4);
return range.Except(banned);
The Enumerable class already has a static method which will return a range of values for you - might be simpler to just use those semantics.
This is one of the ways:
static void Main(string[] args)
{
int[] allNumbers = Enumerable.Range(1, 20).ToArray();
GetNumbers(ref allNumbers, new int[] { 16, 17 });
}
private static void GetNumbers(ref int[] nums, int[]exclude)
{
List<int> numsToExlucde =new List<int>();
numsToExlucde.InsertRange(0, exclude);
nums = nums.Where(w => !numsToExlucde.Contains(w)).ToArray();
}
You have four possible cases. The method could look like this (I assume that range contain integer numbers only):
public class Range
{
public int Start { get; set; }
public int End { get; set; }
public IList<Range> Exclude(Range r)
{
if (r.Start <= Start && r.End < End)
{
return new List<Range>{new Range { Start = r.End + 1, End = End }};
}
else if (r.Start > Start && r.End >= End)
{
return new List<Range>{new Range { Start = Start, End = r.Start - 1 }};
}
else if (r.Start > Start && r.End < End)
{
return new List<Range>
{
new Range { Start = Start, End = r.Start - 1 },
new Range { Start = r.End + 1, End = End }
};
}
return new List<Range>();
}
}
// ...
static void Main(string[] args)
{
Range r = new Range { Start = 1, End = 20};
var list = r.Exclude(new Range{ Start = 1, End = 2} );
}
This can help you remove a range from another, or from a set of ranges:
public class Range {
public int Start { get; private set; }
public int End { get; private set; }
public Range(int start, int end) {
Start = start;
End = end;
}
public IEnumerable<Range> RemoveFrom(Range range) {
return RemoveFrom(new Range[] { range });
}
public IEnumerable<Range> RemoveFrom(IEnumerable<Range> items) {
foreach (Range item in items) {
if (End >= item.Start && Start <= item.End) {
if (item.Start <= Start) {
yield return new Range(item.Start, Start);
}
if (item.End >= End) {
yield return new Range(End, item.End);
}
} else {
yield return item;
}
}
}
}
Example:
Range range = new Range(1, 20);
foreach (Range r in new Range(15,18).RemoveFrom(range)) {
Console.WriteLine("{0} - {1}", r.Start, r.End);
}
Output:
1 - 15
18 - 20
Example of removing multiple ranges from other ranges:
Range[] items = new Range[] { new Range(1, 100), new Range(200, 300) };
Range[] exclude = new Range[] { new Range(25, 75), new Range(250, 280), new Range(90, 210) };
foreach (Range r in exclude) {
items = r.RemoveFrom(items).ToArray();
}
foreach (Range r in items) {
Console.WriteLine("{0} - {1}", r.Start, r.End);
}
Output:
1 - 25
75 - 90
210 - 250
280 - 300
You need to traverse through the banned ranges and iteratively create the valid ranges while doing so.
public List<Range> getValidRanges(Range total, List<Range> banned)
{
List<Range> valid = new ArrayList<Range>();
int start = total.getStartTime();
for(Range range: banned)
{
valid.add(new Range(start,banned.getStart()));
start = banned.getEnd();
}
valid.add(new Range(start,total.getEnd()));
return valid;
}
精彩评论