/*
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*> 数组的查找和排序的更多相关文章

  1. [转]STL中vector转数组(实际是数组的指针)

    感谢:http://topic.csdn.net/t/20050429/20/3976956.html 感谢:http://yzyanchao.blogbus.com/logs/47796444.ht ...

  2. 转:用STL中的vector动态开辟二维数组

    用STL中的vector动态开辟二维数组 源代码:#include <iostream>#include <vector>using namespace std;int mai ...

  3. Java中数组二分法查找

    算法:当数组的数据量很大适宜采用该方法.采用二分法查找时,数据需是有序不重复的,如果是无序的也可通过选择排序.冒泡排序等数组排序方法进行排序之后,就可以使用二分法查找. 基本思想:假设数据是按升序排序 ...

  4. javascript中的Array对象 —— 数组的合并、转换、迭代、排序、堆栈

    Array 是javascript中经常用到的数据类型.javascript 的数组其他语言中数组的最大的区别是其每个数组项都可以保存任何类型的数据.本文主要讨论javascript中数组的声明.转换 ...

  5. 161101、在Java中如何高效判断数组中是否包含某个元素

    如何检查一个数组(无序)是否包含一个特定的值?这是一个在Java中经常用到的并且非常有用的操作.同时,这个问题在Stack Overflow中也是一个非常热门的问题.在投票比较高的几个答案中给出了几种 ...

  6. JS数组2(冒泡排列、数组里面查找数据)

    数组 一.冒泡排列 对数组attr = [1,8,6,4,5,3,7,2,9]进行由大到小排列,用冒泡排列的方法排列时,会对数组进行比较互换.如果前一个数字较大,这2个元素排列方式不变,如果后一个元素 ...

  7. C++中,申请字符串数组可用new实现

    C++中,申请字符串数组可用new实现: char ** list = new char*[MAX_NUM]; for (int i = 0; i< MAX_LOOP; i++) list[i] ...

  8. 【转】java.util.vector中的vector的详细用法

    [转]java.util.vector中的vector的详细用法 ArrayList会比Vector快,他是非同步的,如果设计涉及到多线程,还是用Vector比较好一些 import java.uti ...

  9. java.util.vector中的vector的详细用法

    ArrayList会比Vector快,他是非同步的,如果设计涉及到多线程,还是用Vector比较好一些 import java.util.*; /** * 演示Vector的使用.包括Vector的创 ...

随机推荐

  1. 【VS开发】Windows平台下Makefile学习笔记

    作者:朱金灿 来源:http://blog.csdn.net/clever101 决心学习Makefile,一方面是为了解决编译开源代码时需要跨编译平台的问题(发现一些开源代码已经在使用VS2010开 ...

  2. 向量空间模型(Vector Space Model)

    搜索结果排序是搜索引擎最核心的构成部分,很大程度上决定了搜索引擎的质量好坏.虽然搜索引擎在实际结果排序时考虑了上百个相关因子,但最重要的因素还是用户查询与网页内容的相关性.(ps:百度最臭名朝著的“竞 ...

  3. [学习笔记] 在Eclipse中导入项目

    参考前文:[学习笔记] 在Eclips 中导出项目 选择已经导出的文件: 导入之后,项目结构如下: 至此,完成.

  4. python 使用 RabbitMQ

    一.RabbitMQ消息队列介绍 RabbitMQ是在两个独立得python程序,或其他语言交互时使用. RabbitMQ:erlang语言 开发的. Python中连接RabbitMQ的模块:pik ...

  5. 乐字节Java编程之方法、调用、重载、递归

    一.概述 方法是指人们在实践过程中为达到一定目的和效果所采取的办法.手段和解决方案. 所谓方法,就是解决一类问题的代码的有序组合,是一个功能模块.编程语言中的方法是组合在一起来执行操作语句的集合.例如 ...

  6. 乐字节Java学习01-Java语言概述,Java发展前景,Java的特点

    从这篇文章开始,小乐准备写一整系列的Java学习文章,一步一步带您进入Java的神奇世界! 这是第一篇:Java语言概述以及Java的发展前景 1.SUN公司介绍 SUN公司全称是Stanford U ...

  7. 1、html的concept(概念)和三大基石

    概念:      HMTL:超文本标记语言 作用:      HTML是告诉浏览器接收到的数据使用什么样的数据组织形式进行显示使用:     HTML的规则 1.文件后缀名              ...

  8. Android虚拟机安装apk

    将apk放入platform-tools 打开虚拟机之后 进入该目录执行命令

  9. NoSQL数据库一MongoDB基本使用

    如今的网站对数据存储要求越来越灵活,在这种需求下 NoSQL 也就是非关系数据库越来越流行.所谓非关系数据库,是指不使用 SQL 语言进行数据操作的数据库的统称.这类数据库存储数据时没有固定的模式,不 ...

  10. Java基础---Java方法的重载Overload

    对于功能类似的方法来说,因为参数列表不一样,却需要记住那么多不同的方法名称,太麻烦. 方法的重载(Overload):多个方法的名称一样,但是参数列表不一样.好处:只需要记住唯一一个方法名称,就可以实 ...