set源码之心得
C++的STL很强大,强大到我只愿慵懒地去使用而不知其所以然。直到李师问我,我的回答被李师否定,我方才意识到自己是多么地浅陋。希望自己有空抽时间把STL源码给研究一下,化为自己真正可以掌控的力量。
set容器的原型:template <class Key, class Compare=less<Key>, class Alloc=STL_DEFAULT_ALLOCATOR(Key) >。
在默认情况下,set容器使用less<key>进行比较。而我关心的就是这个less。平时我们会自定义一个比较函数来覆盖less(这里给个set基本用法的链接:http://www.cnblogs.com/jiu0821/p/4190026.html),里面往往是返回一个比较语句。传进去之后,set容器是怎么工作的呢?看过源码的coder会发现,工作原理极为简单:eg:
operator @;//传入的比较符号 type A, B; if (A @ B) ...; else if (B @ A) ...; else ... //得到A与B的“大小”关系
当下有这样一个需求:现有一个数据库,里面记录了若干IP段(即某个范围内所有IP)和IP点(某个IP),现一个用户发来请求报文,我们需要判断该用户的IP是否在数据库中已记录。简化一下,这里的IP简化为一个正整数,大小不超过100。编码实现这个需求的解决方案。
思路:由于存在段和点,我们统一处理为段,即点转化为两端点相同的段,如此,我们求用户IP段与现有集合IP段是否有交集即可。设段为[t1,t2],则利用set容器
if (a.t2 < b.t1) ...; else if (b.t2 < a.t1) ...; else ...;
即为所求。
代码:
1 #include <iostream> 2 #include <set> 3 using namespace std; 4 5 struct info 6 { 7 int t1, t2; 8 bool operator < (const info &r) const 9 { 10 return t2<r.t1; 11 } 12 }; 13 14 set<info> data; 15 16 void Input (); 17 bool Search (); 18 inline void Output (bool); 19 20 int main () 21 { 22 Input (); 23 Output (Search ()); 24 return 0; 25 } 26 27 void Input () 28 { 29 info tmp; 30 int m, n; 31 cin >> m;//时间段 32 for (int i = 1; i <= m; i++) 33 { 34 cin >> tmp.t1 >> tmp.t2; 35 data.insert (tmp); 36 } 37 cin >> n;//时间点 38 for (int i = 1; i <= n; i++) 39 { 40 cin >> tmp.t1; 41 tmp.t2 = tmp.t1; 42 data.insert (tmp); 43 } 44 } 45 bool Search () 46 { 47 info tmp; 48 set<info>::iterator it; 49 cin >> tmp.t1; 50 tmp.t2 = tmp.t1; 51 it = data.find (tmp); 52 if (it != data.end ()) 53 { 54 return true; 55 } 56 else 57 { 58 return false; 59 } 60 } 61 inline void Output (bool tmp) 62 { 63 if (tmp) 64 { 65 cout << "succeed!" 66 << endl; 67 } 68 else 69 { 70 cout << "failed!" 71 << endl; 72 } 73 }