一个泛型算法的设计
2012-06-21 20:48
218 查看
从一个简单的需求开始,从一个vector中返回小于10的数的vector,那我们会写如下的函数:
vector<int> less_than_ten(vector<int>& vec) {
vector<int> result;
for(int i=0; i<vec.size(); i++) {
if (vec[i] < 10) {
result.push_back(vec[i]);
}
}
return result;
}
这个函数只局限于能返回小于10的数,我想能够返回小于我指定的数,于是改成了如下的函数:
vector<int> less_than(vector<int>& vec, int val) {
vector<int> result;
for (int i=0; i < vec[i]; i++) {
if (vec[i] < val)
result.push_back(vec[i]);
}
return result;
}
然后我又考虑到,不应该仅仅是小于,还有可能是大于,或等于。参数化比较函数,于是有了如下的版本 :
bool less_than(int x, int y) {
return x < y;
}
bool greater_than(int x, int y) {
return x > y;
}
vector<int> filter(vector<int>& vec, int val, bool (*pred)(int,int)) {
vector<int> result;
for (int i=0; i < vec.size(); i++) {
if (pred(vec[i],val))
result.push_back(vec[i]);
}
return result;
}
不能仅仅只是int型,如果我们还要float,long,char型 难道都要写一个吗?,不需要,只要使用模板就可以了:
template<typename elemType>
vector<elemType> filter(vector<elemType>& vec, elemType val, bool (*pred) (elemType,elemType)) {
vector<elemType> result;
for (int i=0; i < vec.size(); i++) {
if (pred(vec[i],val))
result.push_back(vec[i]);
}
return result;
}
此时需要注意的是调用的时候,必须保证这三个参数的类型要一致。
在广泛一点我们不仅仅是想使用vector容器,也可以用别的容器,返回的是一个iterator 指向容器中一个元素。
我们使用C++库<algorithm>中的提供的函数对象,和泛型算法.
C++ algorithm库里面提供的 function object 有plus<>,minus<>等等。
参考http://www.cplusplus.com/reference/std/functional/plus/
我们可以使用bind2nd 把它绑定到一个固定的值,与一个固定值进行比较
参考:http://www.cplusplus.com/reference/std/functional/bind2nd/
template<typename elemType,typename Com>
vector<elemType> filter(vector<elemType>& vec, elemType val, Com pred) {
vector<elemType> result;
vector<elemType>::iterator it;
for(; (it = find_if(vec.begin().vec.end(),bind2nd(pred,val))) != vec.end(); it++)
result.push_back(*it);
return result;
}
find_if是在一个范围内查找符合条件的数,并返回该数的位置。 找到最后就是vec.end()了。
for(; (it = find_if(vec.begin().vec.end(),bind2nd(pred,val))) != vec.end(); it++) 这个就是遍历从vec 找到所有符合pred 这个比较函数的值,并把它添加到result里,然后返回。
我们没有必要一开始就能立即写出泛型的函数,可以从简单的开始,一步一步抽象,并参数化。每次写完一个函数的时候,我们应该思考它的扩展性,看能否使其更灵活。这样做非常有助于我们的提高。好的代码要写两次。
参考书目:
《Essential C++》
vector<int> less_than_ten(vector<int>& vec) {
vector<int> result;
for(int i=0; i<vec.size(); i++) {
if (vec[i] < 10) {
result.push_back(vec[i]);
}
}
return result;
}
这个函数只局限于能返回小于10的数,我想能够返回小于我指定的数,于是改成了如下的函数:
vector<int> less_than(vector<int>& vec, int val) {
vector<int> result;
for (int i=0; i < vec[i]; i++) {
if (vec[i] < val)
result.push_back(vec[i]);
}
return result;
}
然后我又考虑到,不应该仅仅是小于,还有可能是大于,或等于。参数化比较函数,于是有了如下的版本 :
bool less_than(int x, int y) {
return x < y;
}
bool greater_than(int x, int y) {
return x > y;
}
vector<int> filter(vector<int>& vec, int val, bool (*pred)(int,int)) {
vector<int> result;
for (int i=0; i < vec.size(); i++) {
if (pred(vec[i],val))
result.push_back(vec[i]);
}
return result;
}
不能仅仅只是int型,如果我们还要float,long,char型 难道都要写一个吗?,不需要,只要使用模板就可以了:
template<typename elemType>
vector<elemType> filter(vector<elemType>& vec, elemType val, bool (*pred) (elemType,elemType)) {
vector<elemType> result;
for (int i=0; i < vec.size(); i++) {
if (pred(vec[i],val))
result.push_back(vec[i]);
}
return result;
}
此时需要注意的是调用的时候,必须保证这三个参数的类型要一致。
在广泛一点我们不仅仅是想使用vector容器,也可以用别的容器,返回的是一个iterator 指向容器中一个元素。
我们使用C++库<algorithm>中的提供的函数对象,和泛型算法.
C++ algorithm库里面提供的 function object 有plus<>,minus<>等等。
参考http://www.cplusplus.com/reference/std/functional/plus/
我们可以使用bind2nd 把它绑定到一个固定的值,与一个固定值进行比较
参考:http://www.cplusplus.com/reference/std/functional/bind2nd/
template<typename elemType,typename Com>
vector<elemType> filter(vector<elemType>& vec, elemType val, Com pred) {
vector<elemType> result;
vector<elemType>::iterator it;
for(; (it = find_if(vec.begin().vec.end(),bind2nd(pred,val))) != vec.end(); it++)
result.push_back(*it);
return result;
}
find_if是在一个范围内查找符合条件的数,并返回该数的位置。 找到最后就是vec.end()了。
for(; (it = find_if(vec.begin().vec.end(),bind2nd(pred,val))) != vec.end(); it++) 这个就是遍历从vec 找到所有符合pred 这个比较函数的值,并把它添加到result里,然后返回。
我们没有必要一开始就能立即写出泛型的函数,可以从简单的开始,一步一步抽象,并参数化。每次写完一个函数的时候,我们应该思考它的扩展性,看能否使其更灵活。这样做非常有助于我们的提高。好的代码要写两次。
参考书目:
《Essential C++》
相关文章推荐
- 如何设计一个泛型算法
- 设计一个泛型算法
- [C++ STL] 一个泛型算法的设计
- [C++ STL] 一个泛型算法的设计
- 对于一个m*n的整数矩阵,其中每一行和每一列的元素都按升序排列,设计一个高效的算法判断一个数值是否存在,并给出位置
- 设计一个算法,判断字符串S是否对称
- 程序员面试金典——解题总结: 9.17中等难题 17.3设计一个算法,算出n阶乘有多少个尾随0
- 设计算法并写出代码移除字符串中重复的字符,不能使用额外的缓存空间。注意: 可以使用额外的一个或两个变量,但不允许额外再开一个数组拷贝。
- 设计一个Android关于24点的小游戏之一(24点算法设计)
- 设计一个算法将两个字符串合并按字母排序
- 两个数组,大小都为n,两个数组里有相同的元素,设计一个算法,找到两个数组中相同的元素
- 设计一个算法,采用BFS方式输出图G中从顶点u到v的最短路径(不带权的无向连通图G采用邻接表存储)
- A,B两个整数集合,设计一个算法求他们的交集
- 我的本科毕业设计(非水文,设计了一个新算法):一种字符编码猜测工具的实现方法
- 程序员面试金典: 9.7数学与概率 7.7有些数的素因子只有3,5,7,请设计一个算法,找出其中第k个数
- 一个信息可视化Demo的设计(三):算法设计
- 转:A、B两个整数集合,设计一个算法求他们的交集,尽可能的高效。
- A,B两个整数集合,设计一个算法求他们的交集,尽可能的高效
- 一串首尾相连的珠子(m个),有N种颜色(N<=10),设计一个算法,取出其中一段,要求包含所有N中颜色,并使长度最短
- 如果字符串的一个子串(其长度大于 1)的各个字符均相同,则称之为等值子串。试设计一算法,求出串S中的最大等值子串 函数返回最大等值子串的长度,如果没有则返回1。 例如: 若S= “abc123abc1