使用 std map 查詢 IP 範圍

2021-08-30 19:03:37 字數 2485 閱讀 2160

給定這樣乙個問題:

有一組從ip範圍到地理位置資訊的資料,不同地點的ip範圍沒有重疊,實現從單個ip位址查到相應的地理位置。

資料示例

view plain

copy to clipboard

print

?

start   end      geo-loc  

1000    2000     北京  

3000    3500     上海  

4000    5000     廣州  

5200    5500     延安  

6000    7000     **

這裡將只重點說明實現方式,具體為什麼這麼做,僅簡單介紹。std::map 有三個不太常用的成員函式:

iterator lower_bound(const key_type& key);

iterator upper_bound(const key_type& key);

pairequal_range(const key_type& key);

實現**:

view plain

copy to clipboard

print

?

#include 

//....

struct

data  

;  // key is the 'end ip address'

typedef

std::mapipmap_t;  

ipmap_t ipmap;  

// load data 

// ..

// find 

ipmap_t::iterator iter = ipmap.upper_bound(ip);  

if(iter != ipmap.end() && iter->second.startip <= ip)

按照stl的慣例,upper_bound 返回的是比查詢的key大的,iter->first 最小的那個iterator。這裡正好利用,找到以後,我們可以保證 ip < iter->first, 也就是ip的上界(開區間上界,不包含),所以,只需要再判斷ip是否大於等於下界,也就是startip,就可以了。

整個過程,相當的簡單,明了,不需要自定義key,不需要多餘的key比較。

為什麼不用startip作為key並且用lower_bound查詢? 我還是說一下吧,lower_bound在查詢失敗時,其結果等於upper_bound,這樣,我們需要對查詢成功和失敗的情況分別處理,邏輯上要複雜很多,並且容易出錯。

使用endip作為key並且使用upper_bound查詢,可以這樣理解:找到endip大於指定ip的第乙個結點,如果這個結點的startip小於等於指定ip,它就是我們要找的結點。

map可以應付執行中新增刪除的情況,如果不需要執行中新增刪除,使用排序的 vector  ,再結合 std::upper_bound 就可以了,速度會更快,並且更省記憶體。具體**,自己動手吧。

同樣的思路,同樣的方法,可以用在作業系統虛擬位址範圍的查詢,檔案偏移範圍的查詢,時間範圍的查詢,等等,等等。

使用 std map 查詢 IP 範圍

給定這樣乙個問題 有一組從ip範圍到地理位置資訊的資料,不同地點的ip範圍沒有重疊,實現從單個ip位址查到相應的地理位置。資料示例 這裡將只重點說明實現方式,具體為什麼這麼做,僅簡單介紹。std map 有三個不太常用的成員函式 iterator lower bound const key type...

std map查詢效率優化

0.現狀,資料是個xml檔案,每個節點對應的結構體有10個成員變數,共有2000多條資料,用的std map來儲存,用map的find函式進行搜尋時的效率極 其低下,迴圈搜尋30條資料竟然要20s 搓死。1.為什麼這麼慢?最初懷疑是std map的效率問題,正考慮是否使用std hast map來替...

std map常見使用錯誤

如下例 std mapm axismapinfo std map 插入資料 for axismap iterator itr m axismapinfo.begin itr m axismapinfo.end itr 在對std map插入資料後,準備進行記憶體刪除。但是。這樣處理一定崩潰 要刪除記...