<commit_before><h2>《Effective STL》 :books: </h2> 

> <NAME> 著    电子工业出版社

```c++
21.总是让比较函数在等值情况下返回 false。
   struct StringPtrGreator:public binary_function<const string*, const string*, bool> {
       bool operator()(const string *ps1, const string *ps2) const {
          return *ps1 > *ps2;
       }
   };

22.切勿直接修改 set 或 multiset 中的键。
   EmpIDSet se;
   Employee selectedID;                           // selectedID 是存储有特定 ID 号的 Employee 变量
   ...
   EmpIDSet::iterator i = se.find(selectedID);    // 第1步：找到待修改的元素
   if (i != se.end()) {
       Employee e(*i);                            // 第2步：拷贝该元素
       e.setTitle("Corporate Deity");             // 第3步：修改拷贝
       se.erase(i++);                             // 第4步：删除该元素；递增迭代器以保持它的有效性
       se.insert(i, e);                           // 第5步：插入新元素，它的位置和原来的相同
   }

23.考虑用排序的 vector 替代关联容器。
```
<commit_msg>Update EffectiveSTL3.md<commit_after><h2>《Effective STL》 :books: </h2> 

> Scott Meyers 著    电子工业出版社

```c++
21.总是让比较函数在等值情况下返回 false。
   struct StringPtrGreator:public binary_function<const string*, const string*, bool> {
       bool operator()(const string *ps1, const string *ps2) const {
          return *ps1 > *ps2;
       }
   };

22.切勿直接修改 set 或 multiset 中的键。
   EmpIDSet se;
   Employee selectedID;                           // selectedID 是存储有特定 ID 号的 Employee 变量
   ...
   EmpIDSet::iterator i = se.find(selectedID);    // 第1步：找到待修改的元素
   if (i != se.end()) {
       Employee e(*i);                            // 第2步：拷贝该元素
       e.setTitle("Corporate Deity");             // 第3步：修改拷贝
       se.erase(i++);                             // 第4步：删除该元素；递增迭代器以保持它的有效性
       se.insert(i, e);                           // 第5步：插入新元素，它的位置和原来的相同
   }

23.考虑用排序的 vector 替代关联容器。
   把排序的 vector 当做映射表来使用，其本质上就如同将它用做一个集合一样。
    vector<Data> vd;                    // 取代 map<string, int>
    ...                                 // 设置阶段：大量的插入，查找却很少
    sort(vd.begin(), vd.end());         // 设置阶段结束(当模拟 multiset 时，你可能选用 stable_sort)
    string s;                           // 用于存放待查找值的对象
    ...                                 // 开始查找阶段
    if (binary_search(vd.begin(), vd.end(), s, DataCompare()))  ...   // 通过 binary_search 查找
    vector<Data>::iterator i = lower_bound(vd.begin(), vd.end(), s, DataCompare()); // 通过 lower_bound 查找
    if (i != vd.end() && !DataCompare()(s, *i))  ...
    pair<vector<Data>::iterator, vector<Data>::iterator> range 
                          = equal_range(vd.begin(), vd.end(), s, DataCompare());   // 通过 equal_range 查找
    if (range.first != range.second()) ...
    ...                                 // 结束查找阶段，开始重组阶段
    sort(vd.begin(), vd.end(), DataCompare());   // 开始新查找阶段...

24.当效率至关重要时，请在 map::operator[] 与 map::insert 之间谨慎做出选择。
   
25.熟悉非标准的散列容器。
```

{'fraction_non_alphanumeric': 0.1446700507614213, 'fraction_numerical': 0.014140681653372008, 'mean_word_length': 1.7316831683168317, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 7, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2355959', 'n_tokens_mistral': 1177, 'n_tokens_neox': 1267, 'n_words': 195}