工作中對涉及到比較多資料的搜尋排序等操作,為了省去資料操作編寫過多相似的排序搜尋代碼,我計劃將stl中的演算法引入到工作中去,增加代碼的精簡程度。 下面就說下find_end的用法。
一、函數說明
find_end:
函數原型:
template <class FdwIt1,class FdwIt2>
FdwIt1 find_end(FdwIt1 first1,FdwIt1 last,FdwIt2 first2,FdwIt2 last2);
template <class FdwIt1,class FdwIt2,class Pred>
FdwIt1 find_end(FdwIt1 first1,FdwIt1 last,FdwIt2 first2,FdwIt2 last2, Pred pr);
功能:在由[first1,last1)標記的序列中尋找“由iteratior對[first2,last2)標記
的第二個序列”的最後一次出現。例如,已知亭子符序列mississippi和第二
個序列ss,則find_end()返回一個FwdIt1指向第二個ss序列的第一個s。如果
在第一個序列中沒有找到第二個序列,則返回last1.在第一個版本中,使用底
層的等於操作符。在第二個版本中,使用使用者傳遞進來的二元操作符pr.
上面是我從別去參考拷貝過來的。此次應用的是第二個內建比較函數的演算法,比如一個複雜的資料結構裡面可能從不同的角度去尋找,如一個學生的結構,可以從學號或是姓名等角度去尋找。另寫的比較演算法有更強的適應性。
二、stl中的原始碼
template<class _FwdIt1, class _FwdIt2,
class _Pr> inline
_FwdIt1 find_end(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2, _FwdIt2 _Last2, _Pr _Pred)
{ // find last [_First2, _Last2) satisfying _Pred
_ASSIGN_FROM_BASE(_First1,
_Find_end(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2), _Pred,
_Dist_type(_First1), _Dist_type(_First2)));
return _First1;
}
//去調用下面的函數進行尋找
template<class _FwdIt1,
class _FwdIt2, class _Diff1, class _Diff2, class _Pr> inline
_FwdIt1 _Find_end(_FwdIt1 _First1, _FwdIt1 _Last1,
_FwdIt2 _First2, _FwdIt2 _Last2, _Pr _Pred, _Diff1 *, _Diff2 *)
{ // find last [_First2, _Last2) satisfying _Pred
_DEBUG_RANGE(_First1, _Last1);
_DEBUG_RANGE(_First2, _Last2);
_DEBUG_POINTER(_Pred);
_Diff1 _Count1 = 0;
_Distance(_First1, _Last1, _Count1);
_Diff2 _Count2 = 0;
_Distance(_First2, _Last2, _Count2);
_FwdIt1 _Ans = _Last1;
if (0 < _Count2)
for (; _Count2 <= _Count1; ++_First1, --_Count1)
{ // room for match, try it
_FwdIt1 _Mid1 = _First1;
for (_FwdIt2 _Mid2 = _First2; ; ++_Mid1)
if (!_Pred(*_Mid1, *_Mid2))//這裡是調用我們的比較函數
break;
else if (++_Mid2 == _Last2)
{ // potential answer, save it
_Ans = _First1;
break;
}
}
return (_Ans);
}
//可以看出其實stl也是進行逐個變數進行比較的。好處是可以不管變數類型,和比較的演算法。這就泛型的優點。
三、樣本程式
#include "stdafx.h"
#include "tchar.h"
#include <vector>
#include <algorithm>
struct student
{
int num;
TCHAR name[32];
public :
student()
{
num = 0;
memset(name, 0, sizeof(TCHAR) * 32);
}
static void Empty(student *s)
{
s->num = 0;
memset(s->name, 0, sizeof(TCHAR) * 32);
}
};
typedef std::vector<student>vst;
typedef std::vector<student>::iterator vstitor;
bool stu_findnum(const student &t1, const student &t2)
{
return t1.num == t2.num;
}
bool stu_findname(const student &t1, const student &t2)
{
return _strcmpi(t1.name, t2.name) == 0;
}
void exam()
{
vst st, st2;
student stu;
int i;
vstitor itor;
for(i = 0; i< 10; i++)
{
student::Empty(&stu);
stu.num = 100 +i;
_stprintf(stu.name, "student %d", i);
st.push_back(stu);
}
student::Empty(&stu);
stu.num = 104;
st2.push_back(stu);
//尋找學號為104的學生
itor = std::find_end(st.begin(), st.end(), st2.begin(), st2.end(),stu_findnum );
if(itor != st.end())
{
printf("student: name = %s num = %d/n", (*itor).name,
(*itor).num);
}
st2.clear();
student::Empty(&stu);
_tcscpy(stu.name , "student 1");
st2.push_back(stu);
//尋找名為student 1學生
itor = std::find_end(st.begin(), st.end(), st2.begin(), st2.end(),stu_findname );
if(itor != st.end())
{
printf("student: name = %s num = %d/n ", (*itor).name,
(*itor).num);
}
}
int main(int argc, char* argv[])
{
exam();
return 0;
}