我有以下代码,根据IP地址获取国家/地区ID:
countryID = GetAllCountryIPRanges().Single(c => c.BeginIPNum <= intIp && intIp <= c.EndIPNum).CountryID;
不幸的是,它的速度非常慢,因为有大约200,000条记录。范围不重叠,GetAllCountryIPRanges()
按BeginIPNum
按升序排列。
如何在此列表中实现.BinarySearch()
以找到正确的记录?
答案 0 :(得分:1)
List有一个二进制搜索方法,但由于二进制搜索很容易实现,因为你需要定义的IComparator是如此复杂,因为范围我建议你实现二进制搜索方法
像这样的东西(没试过!)
public static IPRange BinarySearch(List<IPRange> source, int intIp)
{
int startIndex = 0;
int endIndex = source.Count;
while (endIndex >= startIndex)
{
int middleIndex = startIndex + (endIndex - startIndex) / 2;
if (source[middleIndex].BeginIPNum <= intIp && intIp <= source[middleIndex].EndIPNum)
{
return source[middleIndex];
}
else if (source[middleIndex].BeginIPNum < intIp)
{
startIndex = middleIndex + 1;
}
else
{
endIndex = middleIndex - 1;
}
}
return null;
}
假设列表已排序且没有重叠范围。
答案 1 :(得分:-1)
喜欢递归的优雅......(未经测试)
public static IPRange BinarySearch(IList<IPRange> ipList, int ip)
{
return BinarySearch(source, ip, 0, ipList.Count - 1);
}
public static IPRange BinarySearch(IList<IPRange> ipList, int ip, int min, int max)
{
if (min > max)
{
throw new Assertion("Error: ipList is empty, out-of-order, or does not contain an element that includes the IP");
}
int mid = (min + max) / 2;
var midIp = ipList[mid];
if (ip < midIp.BeginIpNum)
{
return BinarySearch(ipList, ip, min, mid-1);
}
if (ip > midIp.EndIpNum)
{
return BinarySearch(ipList, ip, mid+1, max);
}
return midIp;
}