如何获得数字范围

时间:2011-09-15 18:12:10

标签: c#

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

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

的列表

Range对象可能看起来像那样

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

任何帮助都将不胜感激。

5 个答案:

答案 0 :(得分:43)

这个怎么样?

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

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

答案 1 :(得分:2)

这是其中一种方式:

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

答案 2 :(得分:0)

您有四种可能的情况。该方法可能如下所示(我假设范围仅包含整数):

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

答案 3 :(得分:0)

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

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

答案 4 :(得分:-5)

您需要遍历禁用的范围并在执行此操作时迭代地创建有效范围。

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