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的创 ...
随机推荐
- 关于cookies、sessionStorage和localStorage解释及区别
在浏览器查看 HTML4的本地存储 cookie 浏览器的缓存机制提供了可以将用户数据存储在客户端上的方式,可以利用cookie,session等跟服务端进行数据交互. 一.cookie和sessio ...
- EM算法之不同的推导方法和自己的理解
EM算法之不同的推导方法和自己的理解 一.前言 EM算法主要针对概率生成模型解决具有隐变量的混合模型的参数估计问题. 对于简单的模型,根据极大似然估计的方法可以直接得到解析解:可以在具有隐变量的复杂模 ...
- (二)MVC项目+c3p0连接池
一.项目架构 注:删除了原有的数据库工具,添加了c3p0数据库工具类,添加了c3p0的配置文件,修改了Dao类以及servlet类 二.修改或添加的类 1.C3p0Helper(暂时不了解事务回滚之类 ...
- 【ARM-Linux开发】TI 关于Gstreamer使用的几个参考
http://processors.wiki.ti.com/index.php/Example_GStreamer_Pipelines#H.264_RTP_Streaming http://proce ...
- 关于iframe的一些使用
在iframe页面,获取当前iframe的id var iframeId = window.frameElement.id.toString(); 获取父窗口中另一个iframe的iframe,注意返 ...
- Fiddler之手机抓包
1.Fiddle设置端口,Tools->Options->Connections, 2.手机设置代理服务器: 注意:要保证手机和PC电脑IP在同一个网段(或者同一个网关) (1).安卓手机 ...
- PAT甲级 图的遍历 相关题_C++题解
图的遍历 PAT (Advanced Level) Practice 图的遍历 相关题 目录 <算法笔记>重点摘要 1021 Deepest Root (25) 1076 Forwards ...
- Django导出数据为Excel,调用浏览器下载
1. 环境 Django (2.1.10) + Python3.6 + xlwt (1.3.0) 操作系统使用的为:Windows 7 2. 接口代码 def now_export(request): ...
- cv2.VideoWriter()指定写入视频帧编码格式
帧速率 fps 和 帧大小,通过VideoCapture类的get()函数得到. 编码参数:cv2.VideoWriter_fourcc('I','4','2','0')---未压缩的YUV颜色编码, ...
- 20191011-构建我们公司自己的自动化接口测试框架-Util的AssertResult模块
AssertResult主要就是进行结果断言的了,因为断言结果分2种情况,一种是断言词,一种是断言sheet,如果涉及断言sheet,则需要操作excel到对应的断言表断言所有的字段并且书写断言结果主 ...