Php 查看我的数字是否在一系列范围内的最佳算法是什么?

Php 查看我的数字是否在一系列范围内的最佳算法是什么?,php,algorithm,function,Php,Algorithm,Function,我在php中有一个包含范围的二维数组。例如: From.........To --------------- 125..........3957 4000.........5500 5217628......52198281 52272128.....52273151 523030528....523229183 等等 这是一个很长的清单。现在我想看看用户给出的数字是否在范围内。 例如,数字130、4200、52272933在我的范围内,但数字1560不在我的范围内 当然,我可以数一数所有

我在php中有一个包含范围的二维数组。例如:

From.........To
---------------
125..........3957
4000.........5500
5217628......52198281
52272128.....52273151
523030528....523229183  
等等

这是一个很长的清单。现在我想看看用户给出的数字是否在范围内。 例如,数字130、4200、52272933在我的范围内,但数字1560不在我的范围内

当然,我可以数一数所有的索引,看看我的数字是否大于第一项,是否小于第二项。但是,有没有更快的算法或更有效的方法来使用php函数呢

后来添加 它被分类了。它实际上是使用ip2long()创建的数字,显示一个国家的所有IP。 我刚刚为它写了一段代码:

$ips[1] = array (2,20,100);
$ips[2] = array (10,30,200);
$n=11;// input ip
$count = count($ips);
for ($i = 0; $i <= $count; $i++) {
    if ($n>=$ips[1][$i]){
        if  ($n<=$ips[2][$i]){
            echo "$i found";
            break;
        }
    }else if($n<$ips[1][$i]){echo "not found";break;}
}
$ips[1]=阵列(2,20100);
$ips[2]=阵列(10,30200);
$n=11;//输入ip
$count=计数($ips);
对于($i=0;$i=$ips[1][$i]){

如果($n),则可以通过实现a来加快速度。因此,您不必查看每个范围。 然后,您可以使用来检查该数字是否在数组中

我不确定是否正确,您的阵列是否真的是这样:

array(125, 126, 127, ..., 3957);
a[0] = 125
a[1] = 3957
a[2] = 4000
a[3] = 5500
a[4] = 5217628
a[5] = 52198281
a[6] = 52272128
a[7] = 52273151
a[8] = 523030528
a[9] = 523229183
如果是这样的话,那有什么意义呢?为什么不直接拥有呢

array(125, 3957);

这包含了所有必要的信息。

您给出的示例表明,通过比较,数字可能很大,空间可能很稀疏


在这一点上,你没有太多的选择。如果数组被排序,二进制搜索几乎是所有的。如果数组没有排序,你就只能使用普通的、旧的CS101线性搜索了。

解决这个问题的正确数据结构是一个。一般来说,这比二进制搜索快得多。

将范围放在一个平面数组中,或者ted从低到高,如下所示:

array(125, 126, 127, ..., 3957);
a[0] = 125
a[1] = 3957
a[2] = 4000
a[3] = 5500
a[4] = 5217628
a[5] = 52198281
a[6] = 52272128
a[7] = 52273151
a[8] = 523030528
a[9] = 523229183
然后进行二进制搜索,以确定应在该数组的哪个索引处插入该数字。如果插入索引为偶数,则该数字不在任何子范围内。如果插入索引为奇数,则该数字位于其中一个范围内

示例:

n = 20  inserts at index 0 ==> not in a range
n = 126 inserts at index 1 ==> within a range
n = 523030529 inserts at index 9 ==> within a range

我假设范围不重叠

如果是这种情况,则可以维护键入范围较低值的地图数据结构

现在,您所要做的就是(给定数字N)在映射中找到刚好低于N的键(使用二进制搜索-对数复杂度),然后检查该数字是否小于正确的值


基本上,它是构建地图上的二进制搜索(对数)。

从实用的角度来看,线性搜索很可能是最快的查找方法。请考虑页面错误和硬盘查找时间


如果您的数组足够大(不管“足够”实际上意味着什么),将ip填充到SQL数据库中,让数据库了解如何有效地计算
从ip_编号中选择ID,其中x在开始和结束之间;

这是一个包含长度为2的子数组的二维数组吗?它是否已排序?范围是否重叠?范围排序器是否与i类似在这个例子中?如果没有进一步的限制,您将不得不循环数组并在第一次匹配时停止。@阿尔瓦罗。维卡里奥不,您可以像约翰·R·斯特罗姆和我在回答中提到的那样,使用二进制搜索做得更好(对数)。@middus阿尔瓦罗说的是真的,请注意“没有进一步的限制”。二进制搜索只在数组被分类时才有用。此数组可能看起来像
数组(范围(1253957),范围(40005500),…);
啊,好的:)。谢谢澄清:)@Truth我以为
范围()
将实际创建一个数组,如我的回答中所述!?我的意思是,它是一个范围数组,而不是一个单一的长范围数组。但是,是的,您可以将范围数组简化为这样。(尽管对于这个问题来说,这并不重要)事实上,它是这样的。检查
min是否聪明更有效,这可能是最好的解决方案,但数字不在链中。我没有1到10,10到20,…你的意思是范围不是从低到高排序,或者范围不是相互排斥的?实际上可以使用它。你搜索最小的a[I](从)如果b[i](to)小于值,则在数组中的一个范围内找到值。“一般来说,这比二进制搜索快得多。”这是怎么回事?