1, 默认时使用vector,否则选择其他合适的容器
理由:编程时正确,简单和清晰是第一位的,其次才考虑效率
2, 用vector和string代替数组
例外:如果编译时数组大小就是固定的,则也可以考虑数组
3,在使用容器时候只存储值和智能指针和迭代器
4,容器序列的扩展尽量使用push_back
5,多用范围操作,少用单元操作
6,erase-remove彻底删除元素
理由:Remove算法并不真正地从容器中删除元素,所做的就是移动值的位置,将不应该删除的元素移动到范围的开始处,并返回一个迭代器指向最后一个不应该删除元素的下一个位置,要真正删除,需要在调用remove之后再调用erase:
7, 用算法调用代替手工编写的循环方式
8,使用正确的stl查找算法
(1)查找list中是否有元素10:list<int>::iterator it=find(l.begin(),l.end(), 10);
对于类成员需要重载:
Class Person{
Public:
Persion();
~Persion();
Bool Persion::operator==(constPersion &rhs)const
{
Return (age==rhs.age);
}
Public:
Int age;
};
Persion wantfind;
Wantfind.age=50;
List<Persion>::iterator it=find(l.begin(),l.end(),wantfind);
(2) Map<int,char*> mapItems;
Auto it=find_if(mapItems.begin(),mapItems.end(),[&](const pair<int,char*> &item){
Returnitem->first==0;
})
(3) Count 返回int,统计容器中等于value的个数;count(vector1.begin(),vector1.end(),10)
(4) Count_if返回满足条件的个数,统计容器中大于value的个数:
Template<typename T>
Int GC(vector<int>& num, T filter){
Int n=0;
For(auto&i:num)
{
If(filter(i) == 1){
N++;
}
}
Return n;
}
Count_if(v.begin(),v.end(), GC(vector<int>& num,[=](int x){
Return x>y;
})
b.查找有序范围,应使用lower_bound,upper_bound,equal_range, binary_search
(b.1) Lower_bound将返回一个迭代器,指向第一个匹配(如果存在),或者指向匹配应该处于的位置(如果不存在);(返回一个非递减序列中的第一个大于等于value的位置)
对于无序的要先排序:
Int num[]={10,20,20,30,20,10,20};
Vector<int> v(num,num+7);
Sort(v.begin(),v.end());//10,10,20,20,20,20,30
Vector<int>::iterator low,up;
Low=std::lower_bound(v.begin(),v.end(),20);//low-v.begin()=2-0=2 (b.2) upper_bound将返回一个迭代器,指向最后一个匹配的下一个元素(如果存在),这也是添加下一个等价元素的位置。(返回一个非递减序列中第一个大于value的位置)
up=std::upper_bound(v.begin(),v.end(),20);//up-v.begin=6-0=6 (b.3) 二分查找 binary_search 只能返回一个bool值表示是否找到了匹配
Bool b=binary_search(v.begin(),v.end(),20)9,使用正确的stl排序算法
排序算法开销从低到高排序如下:
前三者是线性时间的,但是我们却很少用到,拾起来呀
(9.1) Nth_element, partial_sort, sort和stable_sort需要随机访问迭代器,如果只有双向迭代器(例如 list<T>::iterator)就无法使用他们。
(9.2) 只有需要保留相等元素的相对顺序不变时候才使用算法的stable_ 版本,请注意 paratial_sort和nth_element都不稳定,无法保留相等元素排序前的相对顺序不变
(9.3) 当然,如果不是非用不可,应该不使用任何排序算法:用标准的关联容器 set/multiset或map/multimap或者 priority_queu适配器,而且只需要一种排列顺序,那么其中的元素将总是有序的。
实例:
1,Partition : 可以将范围恰好分成两组,前面是满足谓词的所有元素,然后是不满足谓词的所有元素。
2,nth_element: 将一个元素放在范围完全排序后她应该处在的第n个位置,同时所有其他元素也会正确地处在第n个元素的前后
3,paratial_sort:除了可以完成nth_element的工作之外,还能使第n个元素之前的元素都处在正确的排序位置上。故可以回答nth_element类似的问题,但同时需要对所匹配的元素进行排序(那些不匹配的元素不需要排序)的问题;
10,避免使用类型分支,多使用多态
类型分支:
Class Shape{
Enum{RECTANGLE, TRIANGLE, CIRCLE} id_;
Void Draw() const{
Switch(id_){
Case RECTANGLE:
//………….
Break;
Case TRANGLE:
//………
Break;
Case CIRCLE:
//…………
Break;
Default:
Assert(!”……….”);
Break;
}
}
};
多态实现:
Class Shape{
Virtual void Draw()const = 0;
};
Temple<class S>
Void Draw(const S& shape){
Shape.Draw();
}11,避免使用 reinterpret_cast
实在要用的话:在不相关的指针类型之间强制转换,应该通过 void* 进行转换,不要直接用reinterpret_cast
不要这样写:
T1* p1=…
T2* p2=reinterpret_cast<T2*>(p1);
要这样写:
T1* p1=….
Void* pV=p1;
T2*p2=static_cast<T2*>(pV);12, 不要使用C风格的强制转换,用C++的代替
C风格:Derived继承自Base
Extern void Fun(Derived*);
Void Gun(Base* pb){
//假设Gun明确知道pb实际上指向的使Derived
//而且先传给Fun
Derived* pd=(Derived*)pb;
Fun(pd);
}
C++风格:
Externvoid Fun(Derived*);
Void Gun(Base* pb){
//假设Gun明确知道pb实际上指向的使Derived
//而且先传给Fun
Derived* pd=static_cast<Derived*>(pb);
//或者 dynamic_cast<Derived*>(pb)
Fun(pd);
}参考:
https://blog.csdn.net/zzhongcy/article/details/87709685
https://blog.csdn.net/alex1997222/article/details/81154386
https://blog.csdn.net/u010510020/article/details/73303187