容器排序方法

    // 排序插入,可以指定在一定范围内排重插入,主要为了指定起始位置,在排序插入时可以避免重复搜索
    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;
    }
posted @ 2016-03-31 23:21  dzqabc  阅读(4)  评论(0编辑  收藏  举报