如何得到数字的范围

本文关键字:范围 数字 何得 | 更新日期: 2023-09-27 18:08:56

我有一个区间数[1,20]。

我想要一个方法,如果我决定禁止范围[15,18],则返回可用数字的范围。我的方法应该返回一个包含[1,15]和[18,20]的列表

Range对象可以是这样的

public class Range
{
     int Start {get;set;}
     int End {get;set;}
}

如何得到数字的范围

这个怎么样?

IEnumerable<int> range = Enumerable.Range(1, 20);
IEnumerable<int> banned = Enumerable.Range(15, 4);
return range.Except(banned);

Enumerable类已经有了一个静态方法,它将为您返回一个范围的值-使用这些语义可能会更简单。

这是一种方法:

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();
    }

有四种可能的情况。该方法可能看起来像这样(我假设范围只包含整数):

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} );
}

这可以帮助您从另一个或一组范围中删除一个范围:

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;
      }
    }
  }
}

的例子:

Range range = new Range(1, 20);
foreach (Range r in new Range(15,18).RemoveFrom(range)) {
  Console.WriteLine("{0} - {1}", r.Start, r.End);
}
输出:

1 - 15
18 - 20

从其他范围中删除多个范围的示例:

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);
}
输出:

1 - 25
75 - 90
210 - 250
280 - 300

您需要遍历被禁止的范围,并在此过程中迭代地创建有效的范围。

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;
}