1

假设您有一个 integer n。假设您有一个不重叠的整数范围列表,例如:

1-9
99-105
160-205
503-600
// many more thousands of ranges, etc ....

我可以很容易地遍历所有这些并检查 n 是否在每个边界之间,如果是则返回 true。那将是 O(n),这很糟糕。这可以在 O(1) 中完成吗?

一些规则:

  • 整数本身非常大并且范围非常宽,因此仅获取可接受整数的完整列表并使用诸如 Set 之类的东西来进行 O(1) 查找是不可行的。在内存中存储这么多整数太昂贵了。我只能存储边界列表。
  • 我将多次运行这个测试,所以我可以预先将列表制作成一些数据结构,如果这样可以使后续查找更有效。

我觉得我可以得到这些范围的二进制表示并构建一棵产生 O(log(n)) 的树。

我真正的问题

我有一个 IP 地址子网列表。我需要测试给定的 IP 是否在这些子网中。我将有很多很多IP要检查。我可以将 IP 转换为整数 (1.2.3.4 => 1*2^32 + 2*2^16 + 3*2^8 + 4)。我可以类似地转换子网。这相当于上面的“更容易解释”的问题。

谢谢!

4

1 回答 1

0

将范围存储在排序向量中并通过 std::lower_bound 搜索值是 O(log(n))。

使用该算法的 IP 200.200.200.200 需要哪个整数大小?为什么不只是 200200200200?

用于存储子网的 IP ABCD 的四分支树似乎更合适。

于 2016-11-18T02:05:03.017 回答