测试一个点是否在一个范围内的例程
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..3] 表示 1 <= x <= 3
并且您不满足(比如)[1..4) 意思是 1 <= x < 4
- 仅限整数
等等
将这些作为假设,需要您搜索 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
谁能帮帮我?
对于 C#
我需要实现一个例程来测试一个点是否在一个范围内(数组),C#
下图中的范围是[1-3],[6-9],[11-15]
我想使用二进制搜索之类的东西,我用过它但是有一个缺陷,因为在这种情况下它只能测试 2 个范围...... 如果我有 2 个范围,则二进制搜索效果很好,因为在 IComparer 中为 2 个范围提供了 2 个事件。 ([1-3],[6-9])
在我添加 3 个范围后,二进制搜索只给我 2 个范围,[6-9]、[11-15]
我正在使用 List
类似的东西---
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..3] 表示 1 <= x <= 3
并且您不满足(比如)[1..4) 意思是 1 <= x < 4 - 仅限整数 等等
将这些作为假设,需要您搜索 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