C++ 中对vector<T*> 数组的查找和排序
/*
2015-06-06 本文主要叙述对于vector<T*> (指针数组)如何进行find 操作下面的代码实现了Find,FindRange 模板函数,
解释了为什么std::find 不能解决问题,
解释了如用find_if来解决问题。
并提供了一个sort 的例子
*/
//--------------------------------------------------------------------------- #include <vcl.h>
#pragma hdrstop #include "Unit1.h"
#include <vector>
#include <algorithm>
using namespace std;
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1; class CA
{
public:
int a; CA(int a)
{
this->a = a;
} bool operator == (int t)
{
return a == t;
}
//无法编译
//friend bool operator == (const CA* ca,int t);
};
//无法编译
/*
bool operator == (const CA* ca,int t)
{
return ca->a == t;
}*/ bool Compare(CA* f, CA* s)
{
return f->a < s->a;
} template<class T1,class T2>
vector<T1*>::iterator Find( vector<T1*>::iterator begin,
vector<T1*>::iterator end,
const T2& var)
{
while(begin != end)
{
if (*(*begin) == var)
{
return begin;
}
begin++;
}
} template<class T1,class T2>
vector<T1*> FindRange( vector<T1*>::iterator begin,
vector<T1*>::iterator end,
const T2& var)
{
vector<T1*> result;
while(begin != end)
{
if (*(*begin) == var)
{
result.push_back(*begin);
}
begin++;
}
return result;
} /***
* 使用find_if
*/
static int globA = ; bool prec (CA* ca)
{
if (globA == ca->a)
return true;
else
return false;
} vector<CA*> arry;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
arry.push_back(new CA());
arry.push_back(new CA());
arry.push_back(new CA());
arry.push_back(new CA());
arry.push_back(new CA());
arry.push_back(new CA());
arry.push_back(new CA());
}
//--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender)
{
sort(arry.begin(),arry.end(),Compare);
for(unsigned i = ; i < arry.size(); i++)
{
ShowMessage(IntToStr(arry[i]->a));
} vector<CA*>::iterator itor = find(arry.begin(),arry.end(),);
if (itor != arry.end())
{
ShowMessage("find!");
} vector<CA*> range = FindRange<CA,int>(arry.begin(),arry.end(),);
ShowMessage("find "+IntToStr(range.size())+" number"); globA = ;
vector<CA*>::iterator itor2 = find_if(arry.begin(),arry.end(),prec);
if (itor2 != arry.end())
{
ShowMessage("find!");
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
for (unsigned i =; i < arry.size() ;i++)
{
delete arry[i];
arry[i] = NULL;
}
arry.clear();
}
//---------------------------------------------------------------------------
上述代码使用模板函数对vector<T*> 类的数组,进行查找。
标准库中的find 比较的方式如下:
template <class _RandomAccessIter, class _Tp>
_STLP_INLINE_LOOP _RandomAccessIter __find(_RandomAccessIter __first, _RandomAccessIter __last,
const _Tp& __val,
const random_access_iterator_tag &)
{
_STLP_DIFFERENCE_TYPE(_RandomAccessIter) __trip_count = (__last - __first) >> ; for ( ; __trip_count > ; --__trip_count) {
if (*__first == __val) return __first; //解除引用然后比较
++__first; if (*__first == __val) return __first;
++__first; if (*__first == __val) return __first;
++__first; if (*__first == __val) return __first;
++__first;
} switch(__last - __first) {
case :
if (*__first == __val) return __first;
++__first;
case :
if (*__first == __val) return __first;
++__first;
case :
if (*__first == __val) return __first;
++__first;
case :
default:
return __last;
}
}
可以看见,标准库的实现是 *__first == __val ,要求实现 == 操作符。
然而,由于vector<T*> 内的元素都是指针,是无论如何也无法 满足==操作符比较的。
至于,为什么vector里面存指针?这关系到运行效率,指针拷贝成本低。
因此,如果vector<T*>这样的数组,基本考虑2种方式find
//自己实现一个Find泛型方法,不过依然要求实现操作符重载。
template<class T1,class T2>
vector<T1*>::iterator Find( vector<T1*>::iterator begin,
vector<T1*>::iterator end,
const T2& var)
{
while(begin != end)
{
if (*(*begin) == var)
{
return begin;
}
begin++;
}
}
或者采用find_if
template <class _RandomAccessIter, class _Predicate>
_STLP_INLINE_LOOP _RandomAccessIter __find_if(_RandomAccessIter __first, _RandomAccessIter __last,
_Predicate __pred,
const random_access_iterator_tag &)
{
_STLP_DIFFERENCE_TYPE(_RandomAccessIter) __trip_count = (__last - __first) >> ; for ( ; __trip_count > ; --__trip_count) {
if (__pred(*__first)) return __first;
++__first; if (__pred(*__first)) return __first;
++__first; if (__pred(*__first)) return __first;
++__first; if (__pred(*__first)) return __first;
++__first;
} switch(__last - __first) {
case :
if (__pred(*__first)) return __first;
++__first;
case :
if (__pred(*__first)) return __first;
++__first;
case :
if (__pred(*__first)) return __first;
// ++__first; 我不知道为什么这里有这样的注释,C++ BUILDER 6 里面的代码就是这样的。可见,标准库也是人写的。
case :
default:
return __last;
}
}
从find_if 的实现可以看出,他的想法是传入一个类或者函数,把元素作为参数代入,如果函数返回true,就满足条件。
因此,使用了一个全局变量(实际应酌情考虑使用类成员)。
/***
* 使用find_if
*/
static int globA = ; bool prec (CA* ca)
{
if (globA == ca->a)
return true;
else
return false;
}
//使用时
globA = 1;
vector<CA*>::iterator itor2 = find_if(arry.begin(),arry.end(),prec);
附带一个sort排序的例子(这个方式和C#,Java 里的方式差不多,只不过 C# 和Java要求传入的是实现ICompare的接口而已,这里是函数指针,本质都是将“行为”传进去)
在元素遍历,查找,排序方面,C#和Java要优雅的多。也许C++11 解决了这个问题,没去研究了。
C++ 中对vector<T*> 数组的查找和排序的更多相关文章
- [转]STL中vector转数组(实际是数组的指针)
感谢:http://topic.csdn.net/t/20050429/20/3976956.html 感谢:http://yzyanchao.blogbus.com/logs/47796444.ht ...
- 转:用STL中的vector动态开辟二维数组
用STL中的vector动态开辟二维数组 源代码:#include <iostream>#include <vector>using namespace std;int mai ...
- Java中数组二分法查找
算法:当数组的数据量很大适宜采用该方法.采用二分法查找时,数据需是有序不重复的,如果是无序的也可通过选择排序.冒泡排序等数组排序方法进行排序之后,就可以使用二分法查找. 基本思想:假设数据是按升序排序 ...
- javascript中的Array对象 —— 数组的合并、转换、迭代、排序、堆栈
Array 是javascript中经常用到的数据类型.javascript 的数组其他语言中数组的最大的区别是其每个数组项都可以保存任何类型的数据.本文主要讨论javascript中数组的声明.转换 ...
- 161101、在Java中如何高效判断数组中是否包含某个元素
如何检查一个数组(无序)是否包含一个特定的值?这是一个在Java中经常用到的并且非常有用的操作.同时,这个问题在Stack Overflow中也是一个非常热门的问题.在投票比较高的几个答案中给出了几种 ...
- JS数组2(冒泡排列、数组里面查找数据)
数组 一.冒泡排列 对数组attr = [1,8,6,4,5,3,7,2,9]进行由大到小排列,用冒泡排列的方法排列时,会对数组进行比较互换.如果前一个数字较大,这2个元素排列方式不变,如果后一个元素 ...
- C++中,申请字符串数组可用new实现
C++中,申请字符串数组可用new实现: char ** list = new char*[MAX_NUM]; for (int i = 0; i< MAX_LOOP; i++) list[i] ...
- 【转】java.util.vector中的vector的详细用法
[转]java.util.vector中的vector的详细用法 ArrayList会比Vector快,他是非同步的,如果设计涉及到多线程,还是用Vector比较好一些 import java.uti ...
- java.util.vector中的vector的详细用法
ArrayList会比Vector快,他是非同步的,如果设计涉及到多线程,还是用Vector比较好一些 import java.util.*; /** * 演示Vector的使用.包括Vector的创 ...
随机推荐
- 【数据库开发】 C连接mysql——常用的函数
转载:http://blog.chinaunix.net/uid-26758020-id-3288633.html 1.MYSQL *mysql_init(MYSQL *mysql) 为mysq ...
- css3 float排序问题
css3 float排序问题 有时候发现 会错位 那是因为有个图片大小不一致才会这样 所以要确保每个图片一样
- python计算平面的法向-利用协方差矩阵求解特征值和特征向量
Obvious,最小特征值对应的特征向量为平面的法向 这个问题还有个关键是通过python求协方差矩阵的特征值和特征向量,np.linalg.eig()方法直接返回了特征值的向量和特征向量的矩阵 sc ...
- 【转载】熟练利用google hacking来辅助我们快速渗透
转载于:https://klionsec.github.io/2014/12/14/search-hacking/?tdsourcetag=s_pcqq_aiomsg 0x01 google hack ...
- postman带Token测试接口
首先打开postman.是这样的界面 我们的需求是这样的.实现登录之后返回token.然后请求其他接口时在header头中带上token信息. OK.接下来我们这样操作: 现在登录没有操作token. ...
- 【C++札记】动态分配内存(malloc,free)
介绍 操作系统中存在一个内存管理器(Memory Manager),简称MM,它负责管理内存. MM提供的服务:应用程序可以向MM申请一块指定大小的内存(借出),用完之后应用程序应该释放(还回). 所 ...
- 使用google的guova开发高并发下的接口限流
使用google的guova开发高并发下的接口限流 使用google的guova进行限流 1.guova的限流方式,在定时产生定量的令牌,令牌的数量限制了流量 2.增加一个订单接口限流类OrderRa ...
- vue.js中 ,回车键实现登录或者提交表单!
vue的功能非常强大,但是我们作为一个后端开发人员,前端的东西不一定都弄的很明白,今天就给大家介绍一个回车提交表单的真实案例,达到回车登录的效果! @ keyup.enter 实现的效果 <in ...
- gin PostForm 方法不起作用
情景: 在httpie post 下,在 axios post下,总的来说,就是在form-data下只有c.Bind()会有用 如果一定要用c.PostForm() headers必须为x-www- ...
- Yii2 基于header 实现接口版本控制
Yii2 官方给出的方案是基于url的版本控制,但是我们的versoin放在header里面,需要通过header来进行版本控制,实现如下: 首先在基类中实现actions,actions是针对con ...