Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据
有些个算法对有序的和无序的数据都能应用,但多数情况下,他们在输入数据有序时才最有用。
下列算法要求输入数据必须有序:
- binary_search, upper_bound, lower_bound, equal_range
这些算法均使用了二分查找 (binary_search) 以期达到 logarithmic-time lookups,要求数据必须有序。
- set_union, set_intersection, set_difference, set_symmeteric_difference
这些算法要求保证时间复杂度为线性,所以输入数据必须有序。
- merge, inplace_merge
这两个算法内部使用 merge sort 来完成运算且要求线性时间,也要求输入必须有序。
- includes
也要求线性时间,输入须有序。
下列算法要求对数据顺序无强制要求,但最好有序:
- unique
- unique_copy
STL 允许我们自己定义排序算法,为了让程序正确的运行,我们必须保证排序时候所用的比较算法和上述的算法中使用的比较算法相同,例如下面的例子中:
vector<int> v; //... putting values to this vector. sort(v.begin(), v.end(), greater<int>); // Sorted in descending order. bool a4Exists = binary_search(v.begin(), v.end(), 5); // Assumes vector sorted in ascending range
试图从降序排列的数据中按照升序算法去找一个数据,很有可能会出问题,而下面的表达式中,在 binary_search 中指定比较算法为排序算法中所使用的比较算法,则没有问题:
bool ret = binary_search(v.begin(), v.end(), 5, greater<int>());
下面是完成的测试代码:
#include <vector> #include <algorithm> #include <iostream> using namespace std; #define N 100 #define show(s,m) cout<< m ;if (s) { cout << " 5 exists!" << endl; } else { cout << " 5 not existed!" << endl; } int main(int argc, char *argv[]) { srand(time(NULL)); vector<int> v(N); for (int i = 0; i < N; ++i) { v[i] = i; } random_shuffle(v.begin(), v.end()); sort(v.begin(), v.end(), greater<int>()); bool ret = binary_search(v.begin(), v.end(), 5); show(ret, "Searching in different compare function:"); ret=binary_search(v.begin(), v.end(), 5, greater<int>()); show(ret, "Searching in same compare function:"); return 0; }
下面是输出:
Welcome to the Emacs shell ~/Documents/MetaWebBlog/org $ ~/tmp $ ./test Searching in different compare function:5 not existed! Searching in same compare function:5 exists!
(转载请注明出处,使用许可:署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议 。)