在指定范围和数量中进行目标查找的一个公用容器

来源:互联网 发布:网络销售项目计划书 编辑:程序博客网 时间:2024/06/06 02:46
//在项目中,我们会遇到这样的需求,查找高玩家5级并低玩家5级的其他玩家,找10个,如果这个区间不够10个,则继续扩大查找范围,这样的话,下面的方法就比较适用于此情况了
/********************************************************************file base:SortTemplatefile ext:hauthor:moonpurpose:用于按指定区间条件进行查找的容器此容器是一个连续的key值(非连续的key不适用)可提供条件区间自动扩大查找功能*********************************************************************/#ifndef _SBASE_SORT_TEMPLATE_H_#define _SBASE_SORT_TEMPLATE_H_#include<list>#include<map>template< typename _TData >class CDataListNumT{public:typedef std::list<_TData> DataList;typedef typename DataList::iterator DataListItr;typedef typename DataList::const_iterator DataListItrC;CDataListNumT():m_nSize(0){}~CDataListNumT(){}void push_back( const _TData& data ){m_List.push_back( data );m_nSize++;}template<class _Iter>void insert(DataListItr _Where, _Iter _First, _Iter _Last){m_List.insert( _Where, _First, _Last );}DataListItr erase( DataListItr itr ){m_nSize--;return m_List.erase( itr );}DataListItr begin(){return m_List.begin();}DataListItrC begin()const{return m_List.begin();}DataListItr end(){return m_List.end();}DataListItrC end()const{return m_List.end();}size_t size()const{return m_List.size();}bool empty()const{return m_List.empty();}size_t general_size()const { return m_nSize; }protected:size_t m_nSize;DataList m_List;};template< typename _TKey, typename _TData >class CSortFindT{public:typedef CDataListNumT<_TData> DataList;typedef typename DataList::DataListItr DataListItr;typedef typename DataList::DataListItrC DataListItrC;typedef std::map< _TKey, DataList > DataKeyVec;typedef typename DataKeyVec::iterator DataKeyVecItr;typedef typename DataKeyVec::const_iterator DataKeyVecItrC;typedef typename DataKeyVec::reverse_iterator DataKeyVecItrR;typedef std::vector< _TData > DataVec;typedef typename DataVec::iterator DataVecItr;typedef typename DataVec::const_iterator DataVecItrC;struct sFindRes{DataKeyVec mOut;//所有符合条件的集合DataVec vlow;//条件以下的集合DataVec vOut;//符合条件的集合DataVec vup;//条件以上的集合};CSortFindT( int nSize = 100 ){for ( int n=0; n<nSize; n++ ){m_vData[n];}}~CSortFindT(){}//加入一条数据void insert( const _TKey& key, const _TData& data ){m_vData[key].push_back(data);}//获取键值数据DataList* find( const _TKey& key ){DataKeyVecItr itr = m_vData.find( key );if ( itr == m_vData.end() )return NULL;return &(itr->second);}//获取指定数据template< typename _M >_TData* find( const _TKey& key, const _M& data ){DataList* pList = find(key);if ( !pList )return NULL;DataListItr itrl = pList->begin();DataListItr itrlE = pList->end();for ( ; itrl != itrlE; ++itrl ){_TData& tmp = *itrl;if ( tmp == data )return &tmp;}return NULL;}//弹出指定数据template< typename _M >bool pop( const _TKey& key, const _M& data, _TData& out ){DataList* pList = find(key);if ( !pList )return false;DataListItr itrl = pList->begin();DataListItr itrlE = pList->end();for ( ; itrl != itrlE; ++itrl ){_TData& tmp = *itrl;if ( tmp == data ){out = tmp;pList->erase(itrl);return true;}}return false;}//删除一条数据template< typename _M >bool erase( const _TKey& key, const _M& data ){_TData out;return pop<_M>( key, data, out );}//更新template< typename _M >bool update( const _TKey& key, const _M& data, const _TKey& tokey ){if ( key == tokey )return false;DataList* pList = find(key);if ( !pList )return false;_TData out;if ( !pop( key, data, out ) )return false;insert( tokey, out );return true;}//查找//从low-up中查找(不包含up),查找指定count,结果返回在mOut中, 如果没有达到指定count,则按照low_step和up_step步长变化继续查找 except表示要排除的template< typename _TCompare >void find_condition( _TKey low, _TKey up, int count, sFindRes& mOut, const _TKey& low_step, const _TKey& up_step, const std::list<_TCompare>& except ){size_t size = m_vData.size();if ( size == 0 )return;std::list<_TCompare> tmpexcept = except;bool bFind = !except.empty();if ( size < 2 ){DataKeyVecItr itr = m_vData.begin();if ( itr->first < low && up_step == 0 )return;if ( itr->first > up && low_step == 0 )return;DataList& list = itr->second;DataListItr itrl = list.begin();DataListItr itrlE = list.end();for ( ; itrl != itrlE; ++itrl ){_TData& tmdata = *itrl;if ( bFind ){if ( IsHaveExcept( tmdata, tmpexcept ) )continue;}if ( itr->first < low )mOut.vlow.push_back( *itrl );else if ( itr->first > up )mOut.vup.push_back( *itrl );elsemOut.vOut.push_back( *itrl );mOut.mOut[itr->first].push_back( *itrl );}return;}if ( low > m_vData.rbegin()->first )return;find_condition( low, up, count, low_step, up_step, tmpexcept );DataKeyVecItr itr = m_vData.find( low );DataKeyVecItr itru = m_vData.find( up );DataKeyVecItr itrE = m_vData.end();if ( itru == itrE ){itru = itrE;}std::list<_TCompare> tmpexcept2 = except;for ( ; itr!=itru; ++itr ){DataList& list = itr->second;DataList& outlist = mOut.mOut[itr->first];bFind = !tmpexcept2.empty();if ( bFind ){DataListItr itrl = list.begin();DataListItr itrlE = list.end();for ( ; itrl != itrlE; ++itrl ){_TData& tmpdata = *itrl;bool bHave = IsHaveExcept( tmpdata, tmpexcept2 );if ( !bHave ){outlist.push_back( tmpdata );if ( itr->first < low )mOut.vlow.push_back( tmpdata );else if ( itr->first > up )mOut.vup.push_back( tmpdata );elsemOut.vOut.push_back( tmpdata );}}}else{outlist.insert( outlist.end(), list.begin(), list.end() );if ( itr->first < low )mOut.vlow.insert( mOut.vlow.end(), list.begin(), list.end() );else if ( itr->first > up )mOut.vup.insert( mOut.vup.end(), list.begin(), list.end() );elsemOut.vOut.insert( mOut.vOut.end(), list.begin(), list.end() );}}}void clear() { m_vData.clear(); }bool empty()const { return m_vData.empty(); }size_t size()const { return m_vData.size(); }DataKeyVec& GetData() { return m_vData; }protected:template< typename _TCompare >bool find_condition( _TKey& low, _TKey& up, int count, const _TKey& low_step, const _TKey& up_step, std::list<_TCompare>& except ){DataKeyVecItr itr = m_vData.find( low );DataKeyVecItr itrE = m_vData.end();bool bBein = false;bool bEnd = false;if ( itr == itrE || low == 0 ){if ( low != 0 )itr = m_vData.begin();bBein = true;}DataKeyVecItr itru = m_vData.find( up );if ( itru == itrE ){itru = itrE;bEnd = true;}size_t nSum = 0;bool bFind = !except.empty();for ( ; itr != itru; ++itr ){DataList& list = itr->second;if ( !bFind )nSum += list.general_size();else{DataListItr itrl = list.begin();DataListItr itrlE = list.end();for ( ; itrl != itrlE; ++itrl ){_TData& tmpdata = *itrl;bool bHave = IsHaveExcept( tmpdata, except );if ( !bHave )nSum++;}}if ( nSum >= count )return true;}if ( bBein && bEnd ){low = m_vData.begin()->first;return true;}if ( low_step == 0 && up_step == 0 )return true;if ( low > low_step )low -= low_step;elselow = 0;up += up_step;return find_condition( low, up, count, low_step, up_step, except );}template< typename _TCompare >bool IsHaveExcept( _TData& tmpdata, std::list<_TCompare>& except ){std::list<_TCompare>::iterator itrex = except.begin();std::list<_TCompare>::iterator itrexE = except.end();for ( ; itrex != itrexE; ++itrex ){if ( tmpdata == (*itrex) ){except.erase( itrex );return true;}}return false;}DataKeyVec m_vData;};typedef CSortFindT<int,int> CSortFindInt;typedef CSortFindT<UINT,UINT> CSortFindUInt;template< typename _TKey, typename _TData >class CSortFindDataT{public:CSortFindDataT( const _TKey& key, const _TData& data ): m_Key(key), m_Data(data){}CSortFindDataT(){}~CSortFindDataT(){}bool operator==( const _TKey& key )const{return m_Key == key;}bool operator==( const CSortFindDataT& data )const{return m_Key == data.m_Key;}template< typename _TCompare >bool operator==( const _TCompare& data )const{return m_Data == data;}_TKey m_Key;_TData m_Data;};#endif