测试一个点是否在一个范围内的例程

Routine that tests if a point is within a range

谁能帮帮我?

对于 C#

我需要实现一个例程来测试一个点是否在一个范围内(数组),C#

下图中的范围是[1-3],[6-9],[11-15]

我想使用二进制搜索之类的东西,我用过它但是有一个缺陷,因为在这种情况下它只能测试 2 个范围...... 如果我有 2 个范围,则二进制搜索效果很好,因为在 IComparer 中为 2 个范围提供了 2 个事件。 ([1-3],[6-9])

在我添加 3 个范围后,二进制搜索只给我 2 个范围,[6-9]、[11-15]

我正在使用 List> 范围和 IComparer>

类似的东西---

class RangeComparerPoint : IComparer<Tuple<int, int>>
    {
        public int Compare(Tuple<int, int> f1, Tuple<int, int> f2)
        {
            //for the sake of clarity
            int boundary_1 = f1.Item1;
            int boundary_2 = f1.Item2;
            int pos = f2.Item1;
            int currPos = f2.Item2;

            //EndSection 
            if (pos > currPos)
            {
                if (pos >= boundary_1 && currPos < boundary_1)
                {
                    //in the range
                    return 0;
                }
            }
            else
            {
                if ( boundary_1 > currPos )
                {
                    return -1;
                }

                if (pos <= boundary_1)
                {
                    //in the range
                    return 0;
                }
            }
            return -1;
        }
    }

你需要更准确地描述问题...

  1. 范围不能重叠(或实施合并它们的逻辑)
  2. 范围都是闭区间,即 [1..3] 表示 1 <= x <= 3
    并且您不满足(比如)[1..4) 意思是 1 <= x < 4
  3. 仅限整数 等等

将这些作为假设,需要您搜索 Tuple<a,a> 以获得值 a(请参阅 Comp() 方法中的异常),这是一个示例如何实现你所追求的...

using System;
using System.Collections;
using System.Collections.Generic;

namespace ConsoleApp2
{
  class Program
  {
    // x represents a point and y a range 
    // (params are swapped if necessary, i.e. if y is a point and x a range)
    // returns 0 if x falls within the range represented by y
    // returns -1 if x falls before y on the number line, +1 if it falls after y
    public static int Comp(Tuple<int, int> x, Tuple<int, int> y)
    {
      var fSwap = 1;
      if (x.Item1 != x.Item2) 
      {
        (x, y) = (y, x); // swap so that x is always the value being searched for
        fSwap = -1;
      }
      if (x.Item1 != x.Item2) // ***
        throw new Exception("The value being sought MUST be new Tuple(a,b) where a == b");
      return fSwap * (x.Item1 < y.Item1 ? -1 : x.Item1 > y.Item2 ? +1 : 0);
    }

    static void Main(string[] args)
    {
      // must be non-overlapping and increasing
      var ranges = new List<Tuple<int, int>>
      {
        new Tuple<int, int>(1, 3),
        new Tuple<int, int>(6, 9),
        new Tuple<int, int>(11,15)
      };

      for (int i = 0; i < 20; i++)
      {
        var foundIn = ranges.BinarySearch(new Tuple<int, int>(i, i), Comparer<Tuple<int, int>>.Create(Comp));
        if (foundIn < 0)
          Console.WriteLine($"{i} does not fall in any range");
        else
          Console.WriteLine($"{i} falls within [{ranges[foundIn].Item1},{ranges[foundIn].Item2}]");
      }
      Console.ReadKey();
    }
  }
}

给出结果...

0 does not fall in any range
1 falls within [1,3]
2 falls within [1,3]
3 falls within [1,3]
4 does not fall in any range
5 does not fall in any range
6 falls within [6,9]
7 falls within [6,9]
8 falls within [6,9]
9 falls within [6,9]
10 does not fall in any range
11 falls within [11,15]
12 falls within [11,15]
13 falls within [11,15]
14 falls within [11,15]
15 falls within [11,15]
16 does not fall in any range
17 does not fall in any range
18 does not fall in any range
19 does not fall in any range