Java 如何存储IP地址范围与位置
我有个问题我有ip地址范围Java 如何存储IP地址范围与位置,java,algorithm,data-structures,Java,Algorithm,Data Structures,我有个问题我有ip地址范围 IP Location 10.1.100.200- 10.1.100.800 x 10.1.101.200- 10.1.101.800 Y 10.1.102.200- 10.1.102.800 Z etc etc 现在给出一个ip,我想找到像eg 10.1.101.270这样的位置,应该给出Y 我不想要的代码,我正试图使
IP Location
10.1.100.200- 10.1.100.800 x
10.1.101.200- 10.1.101.800 Y
10.1.102.200- 10.1.102.800 Z etc etc
现在给出一个ip,我想找到像eg 10.1.101.270这样的位置,应该给出Y
我不想要的代码,我正试图使用最好的算法来存储和搜索它们?
如何处理这个问题
B+Tree?
使用,:可以存储起始范围以映射位置TreeMap
使用红黑树数据结构对条目进行排序。其中,包括插入和移除在内的密钥查找操作是O(log n)
。此地图提供了两个有用的功能:
:返回与严格大于给定键的最小键相关联的键值
映射,或者如果没有此类键,则返回null
:返回与严格小于给定键的最大键关联的键值映射,如果没有此类键,则返回null
当使用特定ip作为键进行搜索时,您可以尝试查找包含起始ip范围作为键及其相应位置作为值的左右条目。使用搜索键比较这些ip范围,以确定值V
(位置)。a或a如何?如果IP地址范围的“集合”是动态的,那么间隔树应该更好;如果范围是静态的,那么段树应该会更好,而且据说在执行“插入式查询”时会更好
区间树:
在计算机科学中,区间树是一种有序的数据树
结构来保持间隔。具体来说,它允许一个人
有效地查找与任何给定间隔或时间重叠的所有间隔
指向它通常用于窗口查询
O的查询时间(日志n)
段树:
在计算机科学中,段树是用于
存储间隔或段。它允许查询存储的
线段包含一个给定的点
查询O(log n+k)中的一个点,k是检索到的间隔或段数
实施:
段树
间隔树。我会按照Sage的建议使用树形图。
假设没有重叠
public class IPSegment implements Comparable<IPSegement>{
private long start;
private long end;
public IPSegement(String startIp, String endIp){
//convert the ip address to a 32 bit integer.
}
public int compareTo(IPSegement other){
return this.start - other.start; //assume no overlap
}
public int equals(IPSegement other){
// check both start and end
}
public boolean contains(long ip){
//check whether 'ip' is in this range
}
}
public class IPSegmentMap{
private TreeMap<IPSegement> map = new TreeMap<IPSegement>();
public void add(String start, String end, String location){
//...
}
public String find(String ipAddress){
long ip = convertIPtoInt(ipAddress);
IPSegement request = new IPSegement(ip,ip);
IPSegement exist = map.floorKey(request);
if(exist.contains(ip)){
return map.get(exist);
}
}
}
public类IPSegment实现了可比较的{
私人长期启动;
私人长尾;
公共IPSEGENT(字符串起始端,字符串结束端){
//将ip地址转换为32位整数。
}
公共内部比较(IPSegement其他){
返回this.start-other.start;//假设没有重叠
}
公共整数等于(IPSegement其他){
//检查起点和终点
}
公共布尔包含(长ip){
//检查“ip”是否在此范围内
}
}
公共类IPSegmentMap{
私有树映射=新树映射();
公共void添加(字符串开始、字符串结束、字符串位置){
//...
}
公共字符串查找(字符串IP地址){
长ip=转换点(ip地址);
IPSEGENT请求=新IPSEGENT(ip,ip);
IPSEGENT exist=map.floorKey(请求);
如果(存在。包含(ip)){
返回map.get(存在);
}
}
}
如何映射IP开始和结束?键和值?@sandy,是的<代码>树映射
根据键
按顺序保存其数据。正如我在回答中提到的,您可能可以通过将所有开始范围保存为键,将相应的位置保存为值来工作。您是否必须解析它,或者值已经存储在某个位置?您的范围重叠,这是有意的吗?如果您有与该数据相关的“记录”,您可以将它们保存在一个数组中,然后进行排序。带有自定义比较器的binarySearch()将返回正确的比较器,或者返回负值,您可以从中找出匹配项,T、 (java.util.Comparator)我可以在logn中更快地搜索吗?我几乎在不知道它存在的情况下发布了关于创建类似于段树的结构的文章。很高兴知道这是一个已经研究过的问题。@sandy我已经在答案中添加了查询时间。@DNax这正是我喜欢的地方,因此,你可以学习新的东西或验证对问题的过渡性思考。