Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 给定IP范围和映射的平面文件,查找给定IP的城市_Algorithm_Search_Data Structures - Fatal编程技术网

Algorithm 给定IP范围和映射的平面文件,查找给定IP的城市

Algorithm 给定IP范围和映射的平面文件,查找给定IP的城市,algorithm,search,data-structures,Algorithm,Search,Data Structures,问题是: 给定一个包含映射的IP地址范围的平面文本文件 到某个位置(例如。 192.168.0.0-192.168.0.255=马萨诸塞州波士顿),提出一种算法,如果存在映射,将为特定ip地址查找城市 我唯一的想法是解析文件,并将IP范围转换为整数(如果缺少数字,则乘以10/100)并将其放入列表中,同时将较低的范围作为键放入哈希,位置作为值。对列表进行排序并执行稍微修改的二进制搜索。如果索引为奇数,-1,请查看散列。如果是偶数,只需查看散列即可 我的计划中有任何错误,或者更好的解决方案吗?在你

问题是:

给定一个包含映射的IP地址范围的平面文本文件 到某个位置(例如。 192.168.0.0-192.168.0.255=马萨诸塞州波士顿),提出一种算法,如果存在映射,将为特定ip地址查找城市

我唯一的想法是解析文件,并将IP范围转换为整数(如果缺少数字,则乘以10/100)并将其放入列表中,同时将较低的范围作为键放入哈希,位置作为值。对列表进行排序并执行稍微修改的二进制搜索。如果索引为奇数,-1,请查看散列。如果是偶数,只需查看散列即可


我的计划中有任何错误,或者更好的解决方案吗?

在你的例子中,192.168.0.0-192.168.0.255=马萨诸塞州波士顿

条目中两个IP地址的前三个八位字节(192.168.0)是否相同? 另外,前三个八位组对一个城市来说是独一无二的吗


如果是这样,那么这个问题就可以更容易地解决

您的方法似乎完全合理

如果你有兴趣做一些研究/额外的编码,有一些算法将逐渐优于标准的二进制搜索技术,这取决于你的IP地址可以被解释为0到231-1范围内的整数。例如,和数据结构可以实现您在时间O(log U)中查看的前置搜索操作,其中U是最大可能的IP地址,而不是二进制搜索使用的O(log N)方法。然而,常数因子更高,这意味着无法保证这种方法会更快。然而,作为另一种可能更快的方法,它可能值得探索


希望这有帮助

这个问题有范围的味道,解决这个问题的一个好的数据结构是段树。来帮助你开始

段树的根可以表示地址(0.0.0.0-255.255.255.255)。左子树表示地址(0.0.0.0-127.255.255.255),右子树表示范围(128.0.0.0-255.255.255),依此类推。这将继续下去,直到我们达到无法进一步细分的范围。比如说,如果我们将范围32.0.0.0-63.255.255.255映射到某个任意城市,它将是一个叶节点,我们到达那里时不会进一步细分该范围,并将其标记到特定城市

要搜索特定的映射,我们遵循树,就像在二叉搜索树中一样。如果您的IP位于左子树的范围内,请移至左子树,否则移至右子树

好的方面是:

  • 您不需要拥有所有子树,只需添加所需的子树。例如,如果在您的数据中,没有为范围(0.0.0.0-127.255.255.255)映射的城市,我们将不构建该子树
  • 我们节省空间。如果整个范围映射到一个城市,我们将只创建根节点
  • 这是一个动态的数据结构。您可以添加更多的城市,稍后拆分范围,等等
  • 由于树的最大深度为4 x log2(256)=32,因此您将进行固定数量的操作。对于这个特殊的问题,结果表明,分段树的速度将与vanemde-Boas树的速度一样快,并且需要更少的空间(O(N))
  • 这是一个简单但不平凡的数据结构,比排序更好,因为它是动态的,比van Emde Boas树更容易向面试官解释
  • 这是最容易编码的非平凡数据结构之一:)
  • 请注意,在某些段树教程中,它们使用数组表示树。这可能不是您想要的,因为我们不会填充整个树,所以动态分配节点,就像我们在标准二叉树中所做的那样是最好的

    我唯一的想法是解析文件,并将IP范围转换为整数(如果缺少数字,则乘以10/100)

    如果采用这种方法,您可能希望将地址A.B.C.D中的A、B、C和D分别乘以256^3、256^2、256和1,从而有效地将IP地址重新创建为32位无符号数

    。。。并将它们放入列表中,同时将范围中较低的部分作为键放入哈希表中,并将位置作为值。对列表进行排序并执行稍微修改的二进制搜索。如果索引为奇数,-1,请查看散列。如果是偶数,只需查看散列即可

    我建议创建一个连续数组(a
    std::vector
    ),其中包含具有上下范围的结构(以及位置名称,如下所述)。然后,正如您所说,您可以对包含特定值的范围进行二进制搜索,而无需任何奇偶麻烦

    使用范围的下端作为散列中的键是避免数组中的位置名称有空格的一种方法,但给定城市名称中的平均字符数,指针的可能大小,在一个稀疏填充的哈希表和一个长位移列表之间进行选择,以便在连续的可选存储桶中搜索,或者进一步间接搜索任意长度的容器——您需要非常迫切地尝试。在第一个实例中,将位置存储在struct中的IP值范围旁边似乎很好


    或者,您可以基于单个0-255 IP值创建树:树中的每个级别可以是256个值的数组,用于直接索引,也可以是填充值的排序数组。这可以减少您可能需要进行的IP值比较的数量(O(log2N)到O(1))。

    不确定。这是我在网上找到的一个面试问题。既然范围是不重叠的,那么分段树不是有点过头了吗?我的理解是,当范围可能重叠时,分段树是好的,但我会