STL中“大”“小” 的概念:
关联容器内部的元素是从小到大排序的
有些算法要求其操作的区间是从小到大排序的,称为“有序区间算法”
例:binary_search
有些算法会对区间进行从小到大排序,称为“排序算法”
例: sort
还有一些其他算法会用到“大”,“小”的概念
使用STL时,在缺省的情况下,以下三个说法等价:
1) x比y小
2) 表达式“x<y”为真
3) y比x大
STL中“相等” 概念:
有时,“x和y相等”等价于“x==y为真” 例:在未排序的区间上进行的算法,如顺序查找find ……
有时“x和y相等”等价于“x小于y和y小于x同时为假” 例: 有序区间算法,如binary_search 关联容器自身的成员函数find ……
#include<iostream>
#include<algorithm>
using namespace std;
class A {
int v;
public:
A(int n):v(n) {}
bool operator<(const A& a2) const {
cout << v << "<" << a2.v << "?" << endl;
return false;
}
bool operator==(const A& a2) const {
cout << v << "==" << a2.v << "?" << endl;
return v == a2.v;
}
};
int main() {
A a[] = {A(1), A(2), A(3), A(4), A(5)};
cout << binary_search(a, a+4, A(9));
return 0;
}
cout:
3<9? 2<9? 1<9? 9<1? 1
算法示例:find()
template InIt find(InIt first, InIt last, const T& val);
first 和 last 这两个参数都是容器的迭代器,它们给出了容器中的 查找区间起点和终点[first,last)。区间的起点是位于查找范围之中 的,而终点不是。find在[first,last)查找等于val的元素
用 == 运算符判断相等
函数返回值是一个迭代器。如果找到,则该迭代器指向被找到的元素。 如果找不到,则该迭代器等于last
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
int main() {
int array[10] = {10, 20, 30, 40};
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
vector<int>::iterator p;
p = find(v.begin(), v.end(), 3);
if (p != v.end())
cout << *p << endl;
p = find(v.begin(), v.end(), 9);
if (p == v.end())
cout << "not found" << endl;
p = find(v.begin()+1, v.end()-2, 1);
if (p != v.end())
cout << *p << endl;
int *pp = find(array, array+4, 20);
cout << *pp << endl;
return 0;
}
cout:
3 not found 3 20
list:
#include<list>
#include<iostream>
#include<algorithm>
using namespace std;
class A {
private:
int n;
public:
A(int n_) { n = n_; }
friend bool operator<(const A& a1, const A& a2);
friend bool operator==(const A& a1, const A& a2);
friend ostream& operator<<(ostream& o, const A& a);
};
bool operator<(const A& a1, const A& a2) {
return a1.n < a2.n;
}
bool operator==(const A& a1, const A& a2) {
return a1.n == a2.n;
}
ostream& operator<<(ostream& o, const A& a) {
o << a.n;
return o;
}
// 定义函数模板PrintList,打印列表中的对象
template<class T>
void PrintList(const list<T>& lst) {
int tmp = lst.size();
if (tmp > 0) {
typename list<T>::const_iterator i;
i = lst.begin();
for (i = lst.begin(); i != lst.end(); ++i) {
cout << *i << ",";
}
}
}
int main(int argc, char const *argv[])
{
list<A> lst1, lst2;
lst1.push_back(1);
lst1.push_back(3);
lst1.push_back(2);
lst1.push_back(4);
lst1.push_back(2);
lst2.push_back(10);
lst2.push_front(20);
lst2.push_back(30);
lst2.push_back(30);
lst2.push_back(30);
lst2.push_front(40);
lst2.push_back(40);
cout << "1)"; PrintList(lst1); cout << endl;
cout << "2)"; PrintList(lst2); cout << endl;
lst2.sort();
cout << "3)"; PrintList(lst2); cout << endl;
lst2.pop_front();
cout << "4)"; PrintList(lst2); cout << endl;
lst1.remove(2); // 删除所有和A(2)相同的元素
cout << "5)"; PrintList(lst1); cout << endl;
lst2.unique(); // 删除所有和前一个元素相同的元素
cout << "6)"; PrintList(lst2); cout << endl;
lst1.merge(lst2); // 合并lst2到lst1并清lst2
cout << "7)"; PrintList(lst1); cout << endl;
cout << "8)"; PrintList(lst2); cout << endl;
lst1.reverse();
cout << "9)"; PrintList(lst1); cout << endl;
lst2.push_back(100);
lst2.push_back(200);
lst2.push_back(300);
lst2.push_back(400);
list<A>::iterator p1, p2, p3;
p1 = find(lst1.begin(), lst1.end(), 3);
p2 = find(lst2.begin(), lst2.end(), 200);
p3 = find(lst2.begin(), lst2.end(), 400);
lst1.splice(p1, lst2, p2, p3); // 将[p2, p3)插入p1之前,
// 并从lst2中删除[p2, p3)
cout << "11)"; PrintList(lst1); cout << endl;
cout << "12)"; PrintList(lst2); cout << endl;
return 0;
}
cout:
1)1,3,2,4,2, 2)40,20,10,30,30,30,40, 3)10,20,30,30,30,40,40, 4)20,30,30,30,40,40, 5)1,3,4, 6)20,30,40, 7)1,3,4,20,30,40, 8) 9)40,30,20,4,3,1, 11)40,30,20,4,200,300,3,1, 12)100,400,
vector:
#include<vector>
#include<iostream>
using namespace std;
int main() {
int i;
int a[5] = {1, 2, 3, 4, 5};
vector<int> v(5);
cout << v.end() - v.begin() << endl;
for (int i = 0; i < v.size(); ++i) {
v[i] = i;
}
v.at(4) = 100;
for (int i = 0; i < v.size(); ++i) {
cout << v[i] << ",";
}
cout << endl;
vector<int> v2(a, a+5);
v2.insert(v2.begin()+2, 13);
for (int i = 0; i < v2.size(); ++i)
cout << v2[i] << ",";
cout << endl;
return 0;
}
cout:
5 0,1,2,3,100, 1,2,13,3,4,5,