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的创 ...
随机推荐
- Java中用FileInputStream和FileOutputStream读写txt文件,文件内容乱码的问题,另附循环代码小错误
乱码问题大概就是编码格式不一样,搜了很多都是这么说的,修改编码解决乱码问题链接: https://blog.csdn.net/weixin_42496466/article/details/81189 ...
- 4、1 IK分词器
我们在浏览器地址栏输入 http://127.0.0.1:9200/_analyze?analyzer=chinese&pretty=true&text=我是程序员 默认的中文分词是将 ...
- 程序计数器(关于java虚拟机内存的那些事)
<深入理解java虚拟机> 读书感悟 作者:淮左白衣 --------------写于2018年4月9日17:44:48 关于java虚拟机内存的那些事之程序计数器 关于java虚拟机内存 ...
- python标准库之collections介绍
collections----容器数据类型 collections模块包含了除list.dict.和tuple之外的容器数据类型,如counter.defaultdict.deque.namedtup ...
- 跟我一起学编程—《Scratch编程》第22课:颠弹力球
1. 能够熟练绘制角色和背景造型 2. 能够熟练控制角色角度.速度等 3. 能够熟练使用变量 4. 能够熟练使用循环.选择等指令控制程序 任务描述: 1. 绘制弹力小球.托板角色,背景造型. 2. 游 ...
- ABP的UnitOfWork内部SaveChanges无效
应用层一个AppService默认是一个工作单元,默认是开启的,默认是事务的.因为应用服务方法应该是原子的且一般都会使用数据库. 但是有些情况需要关闭工作单元 1.AppService有多个操作需要操 ...
- (三十一)web 开发基础项目
1. 编写index.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" ...
- VBA if...elseif...else语句
一个If语句,后面可以跟一个或多个由布尔表达式组成的elseif语句,然后是一个默认的else语句,当所有条件变为false时执行else语句块. 语法 以下是VBScript中If...Elseif ...
- 认识:before和:after伪类
有时候,我们需要大量的重复代码去实现一个非常简单的功能,这不仅浪费时间,而且效率低下,例如: <div class="aa">你好</div><div ...
- 整屏纵向切换超出整屏内容纵向滚动 解决办法-fullpage
这个问题我也是研究了好久,百度了很多办法,swiper我始终没有找到合适的解决办法,所以我放弃了swiper,改用fullpage. fullpage里面有个scrollOverflow的属性: 并且 ...