// 排序插入,可以指定在一定范围内排重插入,主要为了指定起始位置,在排序插入时可以避免重复搜索
template<typename IT, typename T>
inline static bool SCOFindFirst(IT & iter, const IT & end, const T & val)
{
for ( ; end != iter; ++iter)
{
if(*iter >= val)
{
// 相等则找到
return (*iter == val);
}
}
return false;
}
// 排序插入,可以指定在一定范围内排重插入,主要为了指定起始位置,在排序插入时可以避免重复搜索
template<class C, typename T>
inline static bool SCOInsert(C & dest, typename C::iterator & iter, const typename C::iterator & end, const T & val)
{
if(SCOFindFirst(iter, end, val))
{
// 找到重复的,无法插入
return false;
}
else
{
// 在确认找不到的位置插入
dest.insert(iter, val);
return true;
}
}
// 找到A的第一个不在B中的元素
template<typename AIT, typename BIT>
inline static bool SCOFindFirstAnotinB(
AIT & pAIt, const AIT & pAEnd,
BIT & pBIt, const BIT & pBEnd)
{
bool bANotFinished = (pAEnd != pAIt);
bool bBNotFinished = (pBEnd != pBIt);
for (; bBNotFinished && bANotFinished;)
{
if(*pAIt > *pBIt)
{
// 无法确定排除,但对照列表中的可以跳过
++pBIt;
bBNotFinished = (pBEnd != pBIt);
}
else if(*pAIt == *pBIt)
{
// 当前这个已经可以排除,对照列表中的也可以跳过了
++pAIt;
bANotFinished = (pAEnd != pAIt);
++pBIt;
bBNotFinished = (pBEnd != pBIt);
}
else
{
// 找到一个
return true;
}
}
// B遍历完,A未遍历完,则当前元素便是不在B中的
return bANotFinished;
}
template<class C, typename T>
inline static bool SCOInsert(C & dest, const T & val)
{
typename C::iterator iter = dest.begin();
const typename C::iterator end = dest.end();
return SCOInsert(dest, iter, end, val);
}
template<class C, typename T>
inline static bool SCOErase(C & dest, const T & val)
{
typename C::iterator iter = dest.begin();
const typename C::iterator end = dest.end();
if(SCOFindFirst(iter, end, val))
{
// 找到重复的,删除
dest.erase(iter);
return true;
}
else
{
// 找不到
return false;
}
}
// 排序容器操作 A += (B - C)
// 将B中的元素排除掉C中的然后合入A
template<class A, class B, class C>
inline static int SCOAaeBdC(A & a, const B & b, const C & c)
{
int iRet = 0;
typename B::const_iterator pBIt = b.begin();
const typename B::const_iterator pBEnd = b.end();
typename C::const_iterator pCIt = c.begin();
const typename C::const_iterator pCEnd = c.end();
while(SCOFindFirstAnotinB(pBIt, pBEnd, pCIt, pCEnd))
{
// 已经确认不能排除,插入a
if(SCOInsert(a, *pBIt))
{
++iRet;
}
// 从下一个继续
++pBIt;
}
return iRet;
}
// 排序容器操作 AList += (B - C)
// 将B中的元素排除掉C中的然后合入AList
template<class ALM, class B, class C>
inline static int SCOALaeBdC(std::list<ALM> & a, const B & b, const C & c)
{
int iRet = 0;
// list的end及迭代器不会因插入数据而失效
typename std::list<ALM>::iterator pAIt = a.begin();
const typename std::list<ALM>::iterator pAEnd = a.end();
typename B::const_iterator pBIt = b.begin();
const typename B::const_iterator pBEnd = b.end();
typename C::const_iterator pCIt = c.begin();
const typename C::const_iterator pCEnd = c.end();
while(SCOFindFirstAnotinB(pBIt, pBEnd, pCIt, pCEnd))
{
// 已经确认不能排除,插入a
// 因为是排序插入,且list迭代器不会因插入而发生变化,可以避免不断搜索
if(SCOInsert(a, pAIt, pAEnd, *pBIt))
{
++iRet;
}
// 从下一个继续
++pBIt;
}
return iRet;
}
// 排序容器操作 AList += B
template<class ALM, class B>
inline static int SCOALaeB(std::list<ALM> & a, const B & b)
{
int iRet = 0;
typename B::const_iterator pBIt = b.begin();
const typename B::const_iterator pBEnd = b.end();
typename std::list<ALM>::iterator pAIt = a.begin();
const typename std::list<ALM>::iterator pAEnd = a.end();
while(SCOFindFirstAnotinB(pBIt, pBEnd, pAIt, pAEnd))
{
// 已经确认不能排除,插入a
a.insert(pAIt, *pBIt);
++iRet;
++pBIt;
}
return iRet;
}
// 排序容器操作 检查A是否包含B
template<class A, class B>
inline static bool SCOAcontainB(const A & a, const B & b)
{
typename B::const_iterator pBIt = b.begin();
const typename B::const_iterator pBEnd = b.end();
typename A::const_iterator pAIt = a.begin();
const typename A::const_iterator pAEnd = a.end();
if(SCOFindFirstAnotinB(pBIt, pBEnd, pAIt, pAEnd))
{
// 找到B的一个不在A中的元素
return false;
}
return true;
}