C++中,如何使你设计的迭代器被标准算法库所支持。

iterator(读写迭代器)

const_iterator(只读迭代器)

reverse_iterator(反向读写迭代器)

const_reverse_iterator(反向只读迭代器)

以经常介绍的_DList类为例,它的迭代器这样设计:

由于C++17中,std::iterator类模板被弃用,建议不要从std::iterator派生,你可以改为:

例子:


#include "X:\Work\Share\CCode\CPlatform\_std\_forward_list.h"
#include "X:\Work\Share\CCode\CPlatform\base\_List.h"
#include "X:\Work\Share\CCode\CPlatform\Base\_p.h"

using namespace lf;
using namespace std;
using namespace _std;


int main() {
	 
	std::list<int> li1 = { 1,2,3,5 };

	//查找值为5的元素项
	auto it1 = std::find(li1.begin(), li1.end(), 5);

	_cout << _t("------------------------标准库list输出");
	if (it1 != li1.end()) //如果存在
		_cout << *it1 << "\n";

	li1.insert(it1, 4);

	_pn(li1); //打印

	///	 
	
	_list<int> li2 = { 1,2,3,5};

	//查找值为5的元素项
	auto it2 = std::find(li2.begin(), li2.end(),5);

	_cout << _t("------------------------_DList输出");

	if(it2 != li2.end()) //如果存在
		_cout << *it2 << "\n";

	li2.insert(it2, 4); 
	
	_pn(li2);//打印
	 
}

输出结果:

这里最重要的是:

_DList :是一个双向链表
_DListNodeIterator : _DList正向迭代器,继承于std::iterator
std::iterator : 标准库读写迭代器

C++17以下

C++17及其以上:

下面是_DList源码,最后修改于2024-10-06

/************************************************************************
文件名			: _List.h

作者				: 李锋

功能				: 链表

手机				: 13828778863

Email			:  ruizhilf@139.com


创建时间			: 2016年07月31日

最后一次修改时间	:  2024年10月06日


/// 链表是一种用来存储数据集合的数据结构。链表具有如下属性
///(1)元素通过指针依次相连
///(2)最后一个元素的指针为空(null)。
///(3)在程序的执行过程中,链表的长度可以自由伸缩。
///(4)链表的长度可以要求的任意长度(除非系统内存耗尽)。
///(5)它不会浪费内存空间(但会需要额外的内存空间存储指针)。


记住: Virtual C++  Bug:   模板继承用到父类成员访问时,要用 this->

************************************************************************/
#ifndef  __LIST_H_
#define  __LIST_H_

#include "_Macro.h"
#include "_Memory.h"
#include "_ByteArray.h" 
#include "_Pair.h"
#include "_IteratorBase.h"


_LF_BEGIN_

template<class T> class _DList; //前置声明

/// <summary>
/// 排序顺序
/// </summary>
enum class _SortOrder
{
    s_Minmax = 0,   //从小到大   
    s_Maxmin = 1,   //从大到小
    s_null = 2       //无排序顺序
};

  

/// <summary>
///  C#语句:public class _DListNode<T>
/// </summary>
/// <typeparam name="T">默认数据</typeparam>
template<class T>
class _DListNode   
{
public:
    /// <summary>
    /// 节点数据
    /// </summary>
    T Data;


    /// <summary>
    /// 前一个节点
    /// </summary>
    _DListNode<T>* Prev;

    /// <summary>
    /// 下一个节点
    /// </summary>
    _DListNode<T>* Next;


    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="aData">默认数据</param>
    _DListNode(const T& aData)
    {
        Data = aData;
        Prev = null;
        Next = null;
    }

    _DListNode()
    {
        Prev = null;
        Next = null;
        Data = T();
    }
};

 
//------------------------------------------LDIterator
//参考网址:  https://blog.csdn.net/qq_28398301/article/details/106321525          C++用for遍历自定义类


/// <summary>
///  _DList正向迭代器(C++17中,std::iterator类模板被弃用,建议不要从std::iterator派生)
/// </summary>
/// <typeparam name="T"></typeparam>
/// 创建时间:????-??-??    最后一次修改时间:2024-10-06
template<class T>
class _DListNodeIterator //: public std::iterator<_DList<T>, T >
{
public:
    using iterator_category = std::forward_iterator_tag;
    using value_type = T;
    using difference_type = std::ptrdiff_t;
    using pointer = T*;
    using reference = T&;
public:
    /// <summary>
    /// 当前节点
    /// </summary>
    _DListNode<T>* _Ptr;   //命名与标库相同  _pCurrentNode;

    /// <summary>
    /// 当前链表
    /// </summary>
    const _DList<T>*  _pCurrentList;

    inline _DListNodeIterator()
    { 
        _pCurrentList = null;
        _Ptr = null;
    }


    inline _DListNodeIterator(const _DList<T>* pCurrentList)
    {
        assert(pCurrentList != null);
        _pCurrentList = (_DList<T>*)pCurrentList;
        _Ptr = null;
    }

    /// <summary>
    /// 构造函数,传值迭代器管理的值
    /// </summary>
    /// <param name="pNode"></param>
    inline _DListNodeIterator(const _DListNode<T>* pCurrentNode, const  _DList<T>* pCurrentList)
    {
        _Ptr = (_DListNode<T>*)pCurrentNode;
        _pCurrentList = (_DList<T>*)pCurrentList;
    }
     
    inline _DListNodeIterator(const _DListNodeIterator& it)   
    {
        _Ptr = it._Ptr;
        _pCurrentList = it._pCurrentList;
    } 
 
public:   
    /// <summary>
    /// 解引用,取值
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// 创建时间:2024-07-02    最后一次修改时间:2024-07-03
    inline T& operator * () const { return _Ptr->Data; }


    /// <summary>
    /// 向前移动为正,向后移动为负
    /// </summary>
    /// <param name="iDiff"></param>
    /// 创建时间:2024-07-02    最后一次修改时间:2024-07-02
    inline virtual void Move(const int& iDiff) 
    {
        if (iDiff == 0) return;
        
        if (iDiff > 0){
            
            if (_Ptr == null) //已经是最后了,不能向后移了
            { 
                return;
            }
               
            int n = 0;

           
            while (true){

                _Ptr = _Ptr->Next;
                ++n;
                if (n == iDiff){  return; }
            }
        }else{
            int n = 0;
            if (_Ptr == null) {//向前移,减-1进入未尾元素
                _Ptr = _pCurrentList->Last();
                n = -1;  //已经向前移了一位

                if (n == iDiff) { return; }
            }

            while (true){
                _Ptr = _Ptr->Prev;
                --n;

                if (n == iDiff){ return; }
            }
        }

        throw "未重写代码?";
    }

     
    /// <summary>
    /// 
    /// </summary>
    /// <param name="right"></param>
    /// <returns></returns>
    /// 创建时间:2024-07-02    最后一次修改时间:2024-07-02
    inline _DListNodeIterator operator+(const int& iDiff)const {
        _DListNodeIterator itResult(*this);
        itResult.Move(iDiff);
        return itResult;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="right"></param>
    /// <returns></returns>
    /// 创建时间:2024-07-02    最后一次修改时间:2024-07-02
    inline _DListNodeIterator operator-(const int& iDiff)const {
        _DListNodeIterator itResult(*this);
        itResult.Move(-iDiff);
        return itResult;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="r"></param>
    /// <returns></returns>
    /// 创建时间:2024-07-03    最后一次修改时间:2024-07-25
    inline int operator-(const _DListNodeIterator& r)const {

        int n1 = _pCurrentList->FindNodeIndex(_Ptr);
        int n2 = _pCurrentList->FindNodeIndex(r._Ptr);

        //assert(n1 != -1 && n2 != -1);

        //确保 _pCurrentList->end() - _pCurrentList->begin() == _pCurrentList->Count
        //超过边界,指针都设为指向最后一位元素的下一位
        if (n1 == -1)  n1 = _pCurrentList->Count;
        if (n2 == -1)  n2 = _pCurrentList->Count;
 
        return n1 - n2; 
    }

    /// <summary>
    /// 前置加加
    /// </summary>
    /// <returns></returns>
    /// 创建时间:2024-07-02    最后一次修改时间:2024-07-02
    inline _DListNodeIterator& operator++() { Move(1); return  *this; }


    /// <summary>
    /// 前置减减
    /// </summary>
    /// <returns></returns>
    /// 创建时间:2024-07-02    最后一次修改时间:2024-07-02
    inline _DListNodeIterator& operator--() { Move(-1); return  *this; }


    /// <summary>
    /// 后置加加
    /// </summary>
    /// <param name=""></param>
    /// <returns></returns>
    /// 创建时间:2024-07-02    最后一次修改时间:2024-07-02
    inline _DListNodeIterator operator++(int) {
        _DListNodeIterator sResult(*this);
        Move(1);
        return sResult;
    }

    /// <summary>
    /// 后置减减
    /// </summary>
    /// <param name=""></param>
    /// <returns></returns>
    /// 创建时间:2024-07-02    最后一次修改时间:2024-07-02
    inline _DListNodeIterator operator--(int) {
        _DListNodeIterator sResult(*this);
        Move(-1);
        return sResult;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="r"></param>
    /// <returns></returns>
    /// 创建时间:2024-07-02    最后一次修改时间:2024-07-02
    inline _DListNodeIterator& operator+=(const int& iDiff) {
        Move(iDiff);
        return *this;
    }


    /// <summary>
    /// 
    /// </summary>
    /// <param name="r"></param>
    /// <returns></returns>
    /// 创建时间:2024-07-02    最后一次修改时间:2024-07-02
    inline _DListNodeIterator& operator-=(const int& iDiff) {
        Move(iDiff);
        return *this;
    }


    /// <summary>
    ///  关联代码:
    ///  _DList<int> d = { 1,3,53,55,35,97,35,10 };
    ///  d.end() - d.begin(); //8
    /// </summary>
    /// <param name="r"></param>
    /// <returns></returns>
    /// 创建时间:2024-07-03    最后一次修改时间:2024-07-03
    inline int operator-(const _DListNodeIterator& r)
    {
        //note1 到最未尾的索引
        //note2 到最未尾的索引

        int i1 = 0, i2 = 0;

        auto pNode1 = _Ptr;
        auto pNode2 = r._Ptr;


        //pNote1到结点未尾的距离
        while (pNode1 != null)
        {
            pNode1 = pNode1->Next;
            ++i1;
        }

        //pNote2到结点未尾的距离
        while (pNode2 != null)
        {
            pNode2 = pNode2->Next;
            ++i2;
        }

        // - (i1-i2)  值越小,离结点未越近,例如 null 结点,就是 0。
        return  i2 - i1;
    }


    //-------------------------------如果是非线性表,下面的运算符重载也要重写


    inline bool operator!=(const _DListNodeIterator& r) { return this->_Ptr != r._Ptr; }

    inline bool operator==(const _DListNodeIterator& r) { return this->_Ptr == r._Ptr; }

    inline bool operator>(const _DListNodeIterator& r) { return this->_Ptr > r._Ptr; }

    inline bool operator<(const _DListNodeIterator& r) { return this->_Ptr < r._Ptr; }
};



/// <summary>
/// 
/// </summary>
/// <typeparam name="T"></typeparam>
/// 创建时间: 2024-07-03     最后一修改时间:2024-07-03
template<class T>
class _DListNodeReverseIterator
{
public:
    using value_type = T;

private:
    /// <summary>
    /// 当前节点
    /// </summary>
    _DListNode<T>* _pCurrentNode;

    /// <summary>
    /// 当前链表
    /// </summary>
    _DList<T>* _pCurrentList;
public:

    inline _DListNodeReverseIterator()
    {
        _pCurrentList = null;
        _pCurrentNode = null;
    }


    inline _DListNodeReverseIterator(const _DList<T>* pCurrentList)
    {
        assert(pCurrentList != null);
        _pCurrentList = (_DList<T>*)pCurrentList;
        _pCurrentNode = null; 
    }

    /// <summary>
    /// 构造函数,传值迭代器管理的值
    /// </summary>
    /// <param name="pNode"></param>
    inline _DListNodeReverseIterator(const _DListNode<T>* pCurrentNode, const _DList<T>* pCurrentList)
    {
        _pCurrentNode = (_DListNode<T>*)pCurrentNode;
        _pCurrentList = (_DList<T>*)pCurrentList;
    }

    inline _DListNodeReverseIterator(const _DListNodeReverseIterator& it)
    {
        _pCurrentNode = it._pCurrentNode;
        _pCurrentList = it._pCurrentList;
    }

    /// <summary>
    /// 解引用,取值
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// 创建时间:2024-07-02    最后一次修改时间:2024-07-03
    inline T& operator * ()const { return _pCurrentNode->Data; }

    /// <summary>
    /// 前置加加
    /// </summary>
    /// <returns></returns>
    /// 创建时间:2024-07-02    最后一次修改时间:2024-07-02
    inline _DListNodeReverseIterator& operator++() { Move(1); return  *this; }

    /// <summary>
   /// 前置减减
   /// </summary>
   /// <returns></returns>
   /// 创建时间:2024-07-02    最后一次修改时间:2024-07-02
    inline _DListNodeReverseIterator& operator--() { Move(-1); return  *this; }


    /// <summary>
    /// 后置加加
    /// </summary>
    /// <param name=""></param>
    /// <returns></returns>
    /// 创建时间:2024-07-02    最后一次修改时间:2024-07-02
    inline _DListNodeReverseIterator operator++(int) {
        _DListNodeIterator sResult(*this);
        Move(1);
        return sResult;
    }

    /// <summary>
    /// 后置减减
    /// </summary>
    /// <param name=""></param>
    /// <returns></returns>
    /// 创建时间:2024-07-02    最后一次修改时间:2024-07-02
    inline _DListNodeReverseIterator operator--(int) {
        _DListNodeIterator sResult(*this);
        Move(-1);
        return sResult;
    }


    /// <summary>
    /// 向后移动为正,向前移动为负
    /// </summary>
    /// <param name="iDiff"></param>
    /// 创建时间:2024-07-02    最后一次修改时间:2024-07-02
    inline void Move(const int& iDiff) 
    {
        assert(_pCurrentList != null);

        if (iDiff == 0) return;

        if (iDiff > 0) {  //向后移动
            int n = 0;

            if (_pCurrentNode == null) {  //不能向前移动
                _pCurrentNode = _pCurrentList->Last();
                n = 1;  //已经向后移动了一位 
                if (n == iDiff) { return; }
            }
            while (true) {

                _pCurrentNode = _pCurrentNode->Prev;
                ++n;

                if (n == iDiff) { return; }
            }
        }
        else {

            if (_pCurrentNode == null) {  //不能向后移动
                return;
            }


            int n = 0;
            while (true) {
                _pCurrentNode = _pCurrentNode->Next;
                --n;

                if (n == iDiff) { return;}
            }
        }

        throw "未重写代码?";
    }

    inline bool operator!=(const _DListNodeReverseIterator& r) { return this->_pCurrentNode != r._pCurrentNode; }
     

    inline bool operator==(const _DListNodeReverseIterator& r) { return this->_pCurrentNode == r._pCurrentNode; }

    inline bool operator>(const _DListNodeReverseIterator& r) { return this->_pCurrentNode > r._pCurrentNode; }

    inline bool operator<(const _DListNodeReverseIterator& r) { return this->_pCurrentNode < r._pCurrentNode; }
};


/// <summary>
/// 双向链表,  数据 T 要求能够比较大小,否则编译会出错。
/// </summary>
/// <typeparam name="T"></typeparam>
template<class T>
class _DList : public _Object
{
public:
    using value_type = T;
    using iterator = _DListNodeIterator<T>;

    static const size_t  npos = -1;      //不可能的索引  
protected:
    _DListNode<T>*  _First;	        //第一个节点
    _DListNode<T>*  _Last;		    //最后一个节点
    size_t          _Count;			//节点个数
    size_t          _MaxBuffer;     //双链表最大可以存储的元素个数
    _SortOrder      _so;            //排序顺序
protected:

    /// <summary>
    /// 初台化数据
    /// </summary>
    /// <returns></returns>
    inline void InitData() 
    {
        _Count = 0; _First = null; _Last = null; _MaxBuffer = 100000;
        _so = _SortOrder::s_null;
    }


public: //---------------------------------------------------------------------------属性

    __declspec(property(get = GetSortOrder, put = SetSortOrder) )  _SortOrder SortOrder;
    const _SortOrder& GetSortOrder() const { return _so; }
    virtual void SetSortOrder(const _SortOrder so) { _so = so; }



    __declspec(property(get = GetCount)) const int Count;


    /// <summary>
    /// 为了兼容标准库。
    /// 例:T = vector, string, _DList....
    /// size_t nSize = T.size();
    /// auto itBegin = T.begin();
    /// </summary>
    /// <returns></returns>
    /// 创建时间: 2024-07-30     最后一修改时间:2024-07-30
    int size()const { return _Count; }


    inline int GetCount() const { return _Count; }


public:

    //------------------------------------------------------------构造与析构
    
    /// <summary>
    /// 默认构造函数
    /// </summary>
    /// <returns></returns>
    inline _DList()
    {
        InitData();
    }

    /// <summary>
    /// 拷贝[itBegin,itEnd)
    /// </summary>
    /// <param name="itBegin"></param>
    /// <param name="itEnd"></param>
    /// 创建时间: 2024-09-23     最后一修改时间:2024-09-23
    inline _DList(const _DListNodeIterator<T>& itBegin, const _DListNodeIterator<T>& itEnd) {

        InitData();

        _DListNodeIterator<T> it = itBegin;

        while (it != itEnd) {          
            Add(*it);
            ++it;
        }
    }

    inline _DList(const _DList& dl)
    {
        //_cout << _t("inline _DList<T>::_DList(const _DList& dl)\n");

        InitData();

        _DListNode<T>* dn = dl.First();

        while (dn != null)
        {
            Add(dn->Data);

            dn = dn->Next;
        }
    }

    inline _DList(const std::vector<T>& v) {
        InitData();
        for (const T& t : v)
        {
            Add(t);
        }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="v"></param>
    /// 创建时间: 2024-10-01     最后一修改时间:2024-10-01
    inline _DList(const std::forward_list<T>& f) {
        InitData();
        for (const T& t : f)
        {
            Add(t);
        }
    }


    inline _DList (const std::deque<T>& d){
        InitData();
        for (const T& t : d)
        {
            Add(t);
        }
    }


    inline _DList(const T& item) 
    {
        InitData();

        Add(item);
    }


    /// <summary>
    /// 
    /// </summary>
    /// <param name="nCount"></param>
    /// <param name="defaultValue"></param>
    /// 创建时间: 2024-10-01     最后一修改时间:2024-10-01
    inline _DList(const size_t& nCount, const T& defaultValue)
    {
        InitData();
        for (size_t n = 0; n < nCount; ++n) {
            Add(defaultValue);
        }       
    }


    /// <summary>
    /// 列表初始化  dList<int> idl = {1,2,3,4};
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="tList"></param>
    inline _DList(std::initializer_list<T> tList)
    {
        InitData();
        for (T t : tList) { Add(t); }
    }


    /// <summary>
    /// 拷贝区间 [first,end)
    /// </summary>
    /// <param name="first"></param>
    /// <param name="end"></param>
    /// 创建时间: 2024-09-27      最后一次修改时间:2024-09-27  
    inline _DList(const T* first, const T* end) {
        InitData();

        lassert(first != null && end != null);

        T* pt = (T*)first;

        while (pt < end) {
            Add(*pt);
            ++pt;
        }
    }
     

    /// <summary>
    /// 析构函数
    /// </summary>
    inline virtual ~_DList()
    {
        //_cout << _t("inline _DList<T>::~_DList()\n");
        ClearData();
    }


    //------------------------------------------------------------属性

 
    /// <summary>
    /// 双链表最大可以存储的元素个数
    /// </summary>
    int MaxBuffer()const { return _MaxBuffer; }

    /// <summary>
    ///设定双链表最大可以存储的元素个数
    /// </summary>
    /// <param name="nCaptionty"></param>
    inline void MaxBuffer(const size_t  &nCaptionty) { _MaxBuffer = nCaptionty; }


    inline size_t csharp_Count() const { return _Count; }

    inline _DListNode<T>* First()const { return _First; }

    inline _DListNode<T>* Last()const { return _Last; }



    //-----------------------------------------------------------运算符重载

    /// <summary>
    /// 重载的下标操作符 []
    /// </summary>
    const T& operator[](const size_t& nIndex) const {  return IndexOfNode(nIndex)->Data; }
    T& operator[](const size_t& nIndex) { return IndexOfNode(nIndex)->Data; }


    /// <summary>
    /// 重载的下标操作符 =
    /// </summary>
    /// 创建时间: ????-??-??      最后一次修改时间:2024-04-19     
    inline _DList<T>& operator = (const _DList<T>& other)
    {
        if (this != &other)
        {
            ClearData();
            Add(other);              
        }

        return *this;
    }

    
    /// <summary>
    /// 类型转换
    /// </summary>
    inline operator _string() const{ return ToString(); }

    /// <summary>
    /// 类型转换
    /// </summary>
    inline operator _stdstr() const { return ToString().Data; }



 
    //---------------------------------------------------------虚函数重写


    /// <summary>
    /// 是否存在 item
    /// </summary>
    inline virtual bool Contains(const T& item){ return BinarySearch(item) != -1; }


    /// <summary>
    /// 交换两个节点的数据
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="iIndex1"></param>
    /// <param name="iIndex2"></param>
    /// <returns></returns>
    /// 创建时间: ???-??-??      最后一次修改时间:2024-09-20 (改用_Math::swap)    
    inline bool SwapNodeData(const int& iIndex1, const int& iIndex2)
    {
        _DListNode<T>* pNode1, * pNode2;

        pNode1 = IndexOfNode(iIndex1);
        pNode2 = IndexOfNode(iIndex2);

        if (!(pNode1 != null && pNode2 != null))
        {
            return false;
        }

      
        /*
        T ptmp = pNode1->Data;
        pNode1->Data = pNode2->Data;
        pNode2->Data = ptmp;
        */

        _Math::swap(pNode1->Data, pNode2->Data);

        return true;
    }

    /// <summary>
    /// 选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是:第一次从待排序的数据元素中选出最小
    /// 或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序
    /// 的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。选择排序是不稳定的排序方法。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="sortord"></param>
    /// 创建时间: ???-??-??      最后一次修改时间:2024-09-20 (改用_Math::swap)   已测试
    inline virtual void Sort_Selection(const _SortOrder& sortord = _SortOrder::s_Minmax)
    {
        if (_Count == 0 || _Count == 1) return;


        _DListNode<T>* min = _First, * tmp = _First->Next;

        if (sortord == _SortOrder::s_Minmax) //从小到大
        {
            while (min->Next != null)
            {
                while (tmp != null)
                {
                    if (tmp->Data < min->Data)  //交换数据
                    {
                        /*
                        T pt = tmp->Data;
                        tmp->Data = min->Data;
                        min->Data = pt;
                        */
                        _Math::swap(tmp->Data, min->Data);
                    }
                    tmp = tmp->Next;
                }
                min = min->Next;
                tmp = min->Next;
            }
        }
        else
        {
            while (min->Next != null)
            {
                while (tmp != null)
                {
                    if (tmp->Data > min->Data)
                    {
                        /*
                        T pt = tmp->Data;
                        tmp->Data = min->Data;
                        min->Data = pt;
                         */
                        _Math::swap(tmp->Data, min->Data);
                    }
                    tmp = tmp->Next;
                }
                min = min->Next;
                tmp = min->Next;
            }
        }

        this->_so = sortord;  //已排序
    }

    /// <summary>
    /// 返回下标为n的元素的引用。如果下标越界,则抛出-out_of_range异常
    /// </summary>
    /// 创建时间: ???-??-??      最后一次修改时间:2024-09-26  已测试
    inline virtual _DListNode<T>* IndexOfNode(const size_t& nPos)const
    {
        if (nPos >= _Count && _Count != 0 )
            throw ::std::out_of_range("下标越界!");

        size_t nindex = 0;

        if (nPos > _Count / 2)
        {
            _DListNode<T>* pNode = _Last;
            while (pNode != null)
            {
                if (nindex++ == _Count - nPos - 1) { return pNode; }
                pNode = pNode->Prev;
            }
        }
        else
        {
            _DListNode<T>* pNode = _First;
            while (pNode != null)
            {
                if (nindex++ == nPos)
                {
                    return pNode;
                }
                pNode = pNode->Next;
            }
        }
        return null;
    }


    /// <summary>
    /// 把节点移到最后
    /// </summary>
    /// <param name="dnCurrent"></param>
    /// <returns></returns>
    /// 创建时间: 2022-02-18      最后一次修改时间:2024-09-23
    inline virtual _DListNode<T>* MoveLast(_DListNode<T>* pNode)
    {
        if (pNode != null) {

            if (pNode == _Last) {

                //ok

            }else if (pNode == _First) {  //此时最少两个节点

                _First = _First->Next;
                _First->Prev = null;

                _Last->Next = pNode;
                pNode->Prev = _Last;

                _Last = pNode;

                this->_so = _SortOrder::s_null;

            }else {

                pNode->Prev->Next = pNode->Next;
                pNode->Next->Prev = pNode->Prev;

                _Last->Next = pNode;
                pNode->Prev = _Last;
                _Last = pNode;

                this->_so = _SortOrder::s_null;
            }
        }

        return pNode;        
    }

    /// <summary>
    /// 把索引为nIndex的节点移到最后,并返回这个节点。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="iIndex"></param>
    /// <returns></returns>
    /// 创建时间: ???-??-??      最后一次修改时间:2024-09-22  
    inline virtual  _DListNode<T>* MoveLast(const size_t& nIndex)
    {
        return MoveLast(IndexOfNode(nIndex));
    }




    /// <summary>
    /// 把索引为nIndex的节点移到最前
    /// </summary>
    /// <param name="iIndex"></param>
    inline virtual bool MoveFirst(const size_t& nIndex)
    {
        _DListNode<T>* pNode = IndexOfNode(nIndex);

        if (pNode != null)
        {
            if (pNode == _First)
                return true;

            if (pNode == _Last)  //此时最少两个节点
            {
                _Last->Prev->Next = null;
                _Last = _Last->Prev;

                pNode->Prev = null;
                pNode->Next = _First;

                _First->Prev = pNode;

                _First = pNode;

            }
            else
            {
                pNode->Prev->Next = pNode->Next;
                pNode->Next->Prev = pNode->Prev;


                pNode->Next = _First;
                _First->Prev = pNode;
                pNode->Prev = null;

                _First = pNode;

            }

            return true;
        }

        return false;
    }


    /// <summary>
    /// 将指定集合的元素添加到末尾
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="item"></param>
    /// <returns></returns>
    /// 创建时间: ????-??-??      最后一次修改时间:2024-09-22
    inline virtual _DListNode<T>* Add(const T& tValue)
    {
        _DListNode<T>* pResult;

        if (_Count == 0)
        {
            //_First = new _DListNode<T>(item);
            pResult = _Memory::New< _DListNode<T> >(1);

            _First = pResult;
            _First->Data = tValue;
            _First->Next = null;
            _First->Prev = null;
            _Last = _First;
        }
        else
        {
            pResult = _Memory::New< _DListNode<T> >(1);

            pResult->Data = tValue;
            pResult->Next = null;
            pResult->Prev = _Last;

            _Last->Next = pResult;
            _Last = pResult;
        }
        ++_Count;

        this->_so = _SortOrder::s_null;   //要重新排序

        return pResult;
    }

    /// <summary>
    /// 添加一个链表
    /// </summary>
    /// 创建时间: ????-??-??      最后一次修改时间:2024-09-22
    inline _DListNode<T>* Add(const _DList<T>& dList)
    {
        _DListNode<T>* pResult = null;

        _DListNode<T>* pNode = dList._First;
        while (pNode != null)
        {
            if (pResult == null) 
                pResult = Add(pNode->Data);
            else
                Add(pNode->Data);

            pNode = pNode->Next;
        }

        return pResult;
    }


    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="IterClass"></typeparam>
    /// <param name="itBegin"></param>
    /// <param name="itEnd"></param>
    /// <returns></returns>
    /// 创建时间:2024-10-03    最后一次修改时间:2024-10-03
    template<class IterClass>
    const _DList<T>& Add(const IterClass& itBegin,
        const IterClass& itEnd) {

        IterClass it = itBegin;

        while (it < itEnd) {
            Add(*it);
            ++it;
        }

        return *this;
    }

protected:
    /// <summary>
    /// 在结点pItemNode后面插入一个结点,成功,返回新的结点,否则返回NUll;
    /// 如果pItemNote == null,则默认在后面添加一个项。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="pItemNode">当前结点</param>
    /// <param name="rValue"></param>
    /// <returns></returns>
    /// 创建时间: ????-??-??      最后一次修改时间:2024-09-22
    inline virtual _DListNode<T>* InserNodeBack(_DListNode<T>* pNoteItem, const T& tValue)
    {
        if (pNoteItem == null || _Count == 0) return this->Add(tValue);

        this->SortOrder = _SortOrder::s_null;

        _DListNode<T>* pNode = _Memory::New<_DListNode<T>>(1);
        pNode->Data = tValue;


        //pNode
        pNode->Prev = pNoteItem;
        pNode->Next = pNoteItem->Next;



        //pListItem->Next
        if (pNoteItem->Next != null) {

            pNoteItem->Next->Prev = pNode;

        }else{
            _Last = pNode;
        }
         
        //--pNoteItem
        pNoteItem->Next = pNode;


        ++_Count;

        return pNode;

    }

    /// <summary>
    /// 在结点pNoteItem前面插入一个结点,成功,返回新的结点,否则返回null
    /// 如果pItemNote == null,则默认在后面添加一个项。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="pListItem"></param>
    /// <param name="rData"></param>
    /// <returns></returns>
    /// 创建时间: ????-??-??      最后一次修改时间:2024-09-22
    inline virtual _DListNode<T>* InserNodeFront(_DListNode<T>* pNoteItem, const T& tValue)
    {
        if (pNoteItem == null || _Count == 0) return this->Add(tValue);

        this->SortOrder = _SortOrder::s_null;

        if (pNoteItem == null) return null;

        _DListNode<T>* pNode = _Memory::New<_DListNode<T>>(1);
        pNode->Data = tValue;


        //pNode            
        pNode->Next = pNoteItem;
        pNode->Prev = pNoteItem->Prev;



        //--pListItem->Prev
        if (pNoteItem->Prev != null){

            pNoteItem->Prev->Next = pNode;

        }else{

            _First = pNode;
        }

        //pNoteItem
        pNoteItem->Prev = pNode;


        ++_Count;

        return pNode;

    }


    //------------------------------------------------------------操作         
public:

 
    /// <summary>
    /// 如果已排好序,它会按二分法查找,否则它会普通查找。
    /// </summary>
    /// <param name="item"></param>
    /// <returns></returns>
    /// 创建时间: ????-??-??      最后一次修改时间:????_??_??       已测试
    inline int BinarySearch(const T& item)const {
        switch (this->_so)
        {
        case _SortOrder::s_Maxmin:
        {
            if (_Count == 0)
            {
                return -1;
            }
            if (_Count == 1)
            {
                //return (_First.Data as IComparable).CompareTo(item) == 0 ? 0 : -1;  //C#

                return _First->Data == item ? 0 : -1;
            }
            if (_Count == 2)
            {
                //if ((_First.Data as IComparable).CompareTo(item) == 0) return 0;
                //if ((_First.Next.Data as IComparable).CompareTo(item) == 0) return 1;
                if (_First->Data == item) return 0;
                if (_First->Next->Data == item) return 1;

                return -1;
            }

            int nPos = (int)_Count / 2;   //nPos在中间,所以无素一定要大于等于3才行
            int nLeft = 0;   //左边远素
            int nRight = (int)_Count - 1;  //右边远素

            _DListNode<T>* pNode;

            while (nRight >= 0 && nLeft >= 0)
            {
                pNode = IndexOfNode(nPos);

                //int iCom = (item as IComparable).CompareTo(ld.Data);


                if (item > pNode->Data)
                {
                    if (nRight == nLeft || nPos == nLeft)
                    {
                        return -1;
                    }
                    nRight = nPos - 1;
                }
                else if (item < pNode->Data)
                {
                    if (nRight == nLeft || nPos == nRight)
                    {
                        return -1;
                    }
                    nLeft = nPos + 1;
                }
                else
                {
                    return nPos;
                }
                nPos = nLeft + (nRight - nLeft + 1) / 2;
            }

            break;
        }
        case _SortOrder::s_Minmax:
        {
            if (_Count == 0)
            {
                return -1;
            }
            if (_Count == 1)
            {
                //return (_First.Data as IComparable).CompareTo(item) == 0 ? 0 : -1;
                return _First->Data == item ? 0 : -1;
            }
            if (_Count == 2)
            {
                //if ((_First.Data as IComparable).CompareTo(item) == 0) return 0;
                //if ((_First.Next.Data as IComparable).CompareTo(item) == 0) return 1;
                if (_First->Data == item) return 0;
                if (_First->Next->Data == item) return 1;
                return -1;
            }


            int nPos = (int)_Count / 2;   //nPos在中间,所以无素一定要大于等于3才行
            int nLeft = 0;   //左边远素
            int nRight = (int)_Count - 1;  //右边远素

            _DListNode<T>* pNode = null;

            while (nRight >= 0 && nLeft >= 0)
            {
                pNode = IndexOfNode(nPos);
                //int iCom = (item as IComparable).CompareTo(ld.Data);

                if (item < pNode->Data)
                {
                    if (nRight == nLeft || nPos == nLeft)
                    {
                        return -1;
                    }
                    nRight = nPos - 1;
                }
                else if (item > pNode->Data)
                {
                    if (nRight == nLeft || nPos == nRight)
                    {
                        return -1;
                    }
                    nLeft = nPos + 1;
                }
                else
                {
                    return nPos;
                }
                nPos = nLeft + (nRight - nLeft + 1) / 2;
            }
            break;
        }
        case _SortOrder::s_null:
        {
            _DListNode<T>* pNode = _First;
            int iCount = 0;
            while (pNode != null)
            {
                if (pNode->Data == item)
                {
                    return iCount;
                }
                pNode = pNode->Next;
                ++iCount;
            }
            break;
        }
        default:
        {
            return -1;
        }
        }
        return -1;
    }



    /// <summary>
    /// 清除节点,并释放内存
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// 创建时间: ????-??-??      最后一次修改时间:2022-12-24    (已测试)
    inline void ClearData() override { ClearMemory(); }


    /// <summary>
    /// 清除节点,并释放内存
    /// </summary>
    inline void ClearMemory() override
    {
        _Count = 0;

        _DListNode<T>* dn = _First;
        while (dn != null)
        {
            if (dn->Prev != null)
                _Memory::Delete< _DListNode<T> >(dn->Prev, 1);
            dn = dn->Next;
        }

        if (_Last != null)
            _Memory::Delete< _DListNode<T> >(_Last, 1);

        _First = null;
        _Last = null;
        this->_so = _SortOrder::s_null;
    }

    /// <summary>
    /// 复制一个链表,清除原来链表的数据
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="ld"></param>
    inline void CopyFrom(const _DList<T>& ld)
    {
        if (this != &ld)
        {
            ClearData();
            _DListNode<T>* pNode = ld._First;
            while (pNode != null)
            {
                Add(pNode->Data);
                pNode = pNode->Next;
            }
        }
    }



    /// <summary>
    /// 移除指定索引处的元素
    /// </summary>
    /// <typeparam name="T">类型</typeparam>
    /// <param name="iIndex">要移除的元素的从零开始的索引。</param>
    /// <returns>成功返回true,否则返回false</returns>
    /// 创建时间:????-??-?? 最后一次修改时间:2023-04-08
    inline bool RemoveAt(const size_t& nIndex)
    {
        if (nIndex >= _Count) return false;
    
        _DListNode<T>* pNode = _First;

        size_t  nCount = 0;
        while (pNode != null)
        {
            if (nCount == nIndex)
            {
                if (pNode == _First)
                {
                    if (_First->Next == null)   //只有一个
                    {
                        ClearData();
                        return true;
                    }
                    else
                    {

                        _First = _First->Next;
                        _First->Prev = null;
                        --_Count;

                        _Memory::Delete<  _DListNode<T> >(pNode, 1);

                        return true;
                    }
                }
                else if (pNode == _Last)
                {

                    if (_Last->Prev == null)
                    {
                        ClearData();
                        return true;
                    }
                    else
                    { 

                        _Last = _Last->Prev;
                        _Last->Next = null;
                        --_Count;

                        _Memory::Delete< _DListNode<T>>(pNode, 1);

                        return true;
                    }
                }
                else
                {
                    pNode->Prev->Next = pNode->Next;
                    pNode->Next->Prev = pNode->Prev;

                    --_Count;

                    _Memory::Delete< _DListNode<T>>(pNode, 1);
                    return true;
                }
            }
            pNode = pNode->Next;
            ++nCount;
        }
        return false;
    }


 

    
    /// <summary>
    /// 在节点中查找一项数据,这项数据值与tData相同
    /// </summary>
    /// <param name="tData"></param>
    /// <returns></returns>
    /// 创建时间:????-??-?? 最后一次修改时间:2024-09-20
    inline _DListNode<T>* FindNodeItem(const T& tValue)const
    {
        switch (this->_so)
        {
        case _SortOrder::s_Maxmin:
        {
            if (_Count == 0)
            {
                return null;
            }
            if (_Count == 1)
            {
                //return (_First.Data as IComparable).CompareTo(tValue) == 0 ? _First : null;
                return _First->Data == tValue ? _First : null;
            }
            if (_Count == 2)
            {
                //if ((_First.Data as IComparable).CompareTo(tValue) == 0) return _First;
                //if ((_First.Next.Data as IComparable).CompareTo(tValue) == 0) return _First.Next;

                if (_First->Data == tValue) return _First;
                if (_First->Next->Data == tValue) return _First->Next;
                return null;
            }

            int nPos = (int)(_Count / 2);   //nPos在中间,所以无素一定要大于等于3才行
            int nLeft = 0;   //左边远素
            int nRight = (int)(_Count - 1);  //右边远素

            _DListNode<T>* pNode = null;

            while (nRight >= 0 && nLeft >= 0)
            {
                pNode = IndexOfNode(nPos);

                //int iCom = (tValue as IComparable).CompareTo(ld.Data);

                if (tValue > pNode->Data)
                {
                    if (nRight == nLeft || nPos == nLeft)
                    {
                        return null;
                    }
                    nRight = nPos - 1;
                }
                else if (tValue < pNode->Data)
                {
                    if (nRight == nLeft || nPos == nRight)
                    {
                        return null;
                    }
                    nLeft = nPos + 1;
                }
                else
                {
                    return pNode;
                }
                nPos = nLeft + (nRight - nLeft + 1) / 2;
            }

            break;
        }
        case _SortOrder::s_Minmax:
        {
            if (_Count == 0)
            {
                return null;
            }
            if (_Count == 1)
            {
                //return (_First.Data as IComparable).CompareTo(tValue) == 0 ? _First : null;
                return _First->Data == tValue ? _First : null;
            }
            if (_Count == 2)
            {
                //if ((_First.Data as IComparable).CompareTo(tValue) == 0) return _First;
                //if ((_First.Next.Data as IComparable).CompareTo(tValue) == 0) return _First.Next;

                if (_First->Data == tValue) return _First;
                if (_First->Next->Data == tValue) return _First->Next;

                return null;

            }


            int nPos = (int)(_Count / 2);   //nPos在中间,所以无素一定要大于等于3才行
            int nLeft = 0;   //左边远素
            int nRight = (int)(_Count - 1);  //右边远素

            _DListNode<T>* pNode = null;

            while (nRight >= 0 && nLeft >= 0)
            {
                pNode = IndexOfNode(nPos);

                //int iCom = (tValue as IComparable).CompareTo(ld.Data);

                if (tValue < pNode->Data)
                {
                    if (nRight == nLeft || nPos == nLeft)
                    {
                        return null;
                    }
                    nRight = nPos - 1;
                }
                else if (tValue > pNode->Data)
                {
                    if (nRight == nLeft || nPos == nRight)
                    {
                        return null;
                    }
                    nLeft = nPos + 1;
                }
                else
                {
                    return pNode;
                }
                nPos = nLeft + (nRight - nLeft + 1) / 2;
            }
            break;
        }
        case _SortOrder::s_null:
        {
            _DListNode<T>* pNode = _First;

            while (pNode != null)
            {
                //总结:Equals比较的永远是变量的内容是否相同,而= =比较的则是引用地址是否相同(前提:此种类型内部没有对Equals 或= = 进行重写操作,
                //否则输出可能会有不同)。string 类型是个特例,因为他的内部对这两个都进行了重写。

                if (tValue == pNode->Data)
                {
                    return pNode;
                }

                /*
                if (pNode.Data.Equals(tValue))
                {
                    return pNode;
                }
                */
                pNode = pNode->Next;
            }
            break;
        }
        default:
        {
            return null;
        }
        }
        return null;
    }


    inline _DListNode<T>* Find(const T& tValue)const { return FindNodeItem(tValue); }

    /// <summary>
    /// 在链接中查找节点,返回节点的索引,如果没找到,返回-1
    /// </summary>
    /// <param name="pFind"></param>
    /// <returns></returns>
    /// 创建时间:2024-07-03 最后一次修改时间:2024-07-03
    inline int FindNodeIndex(const _DListNode<T>* pFind)const
    {
        if (pFind != null){

            _DListNode<T>* pNode = _First;

            int nIndex = 0;
            while (pNode != null){

                if (pNode == pFind)
                    return nIndex;

                pNode = pNode->Next;
                ++nIndex;  
            }
        }
        return -1;
    }


    /// <summary>
    /// 删除链表中的数据
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="pData"></param>
    /// <returns></returns>
    inline bool RemoveItem(const T& pData)
    {
        if (this->_so == _SortOrder::s_null)
        {
            _DListNode<T>* pNode = _First;

            while (pNode != null)
            {
                if (pNode->Data == pData)	//找到一项
                {
                    if (pNode == _First)		//删除的是第一个节点
                    {
                        if (_First->Next != null)
                        {
                            _First->Next->Prev = null;
                            _First = _First->Next;
                        }
                        else
                        {
                            _First = null;
                            _Last = null;
                        }
                    }
                    else if (pNode == _Last)  //删除的是最后一个节点
                    {
                        if (_Last->Prev != null)
                        {
                            _Last->Prev->Next = null;
                            _Last = _Last->Prev;
                        }
                        else
                        {
                            _Last = null;
                            _Last = null;
                        }
                    }
                    else						//删除的是中间的一个节点
                    {
                        pNode->Next->Prev = pNode->Prev;
                        pNode->Prev->Next = pNode->Next;
                    }
                    --_Count;
                    return true;
                }

                pNode = pNode->Next;

            }

            return false;
        }
        else
        {
            return RemoveAt(BinarySearch(pData));
        }
    }



    /// <summary>
    /// 删除最后一个节点
    /// </summary>
    /// 创建时间:2020-09-12  最后一次修改时间: 2023-01-18
    inline bool DeleteLast()
    {
        auto pDelete = Last();

        if (_Count <= 0)
        {
            return false;
        }
        else if (_Count == 1)
        {
            _First = null;
            _Last = null;
            _Count = 0;
        }
        else if (_Count == 2)
        {
            _Last = _First;
            _Last->Prev = null;
            _Last->Next = null;

            _First->Next = null;
            _First->Prev = null;

            --_Count;
        }
        else
        {
            _Last->Prev->Next = null;

            _Last = _Last->Prev;

            --_Count;
        }

        _Memory::Delete<_DListNode<T>>(pDelete, 1);

        return true;
    }

    /// <summary>
    /// 添加一个元素,并把它放在首位,其它元素后移,如果后面的元素删除,总无素个数不变,如果元素个数为零,则添加一个无素。
    /// </summary>
    /// <param name="Item"></param>
    /// <param name="bRemoveLast"></param>
    /// 创建时间: 2022-04-19      最后一次修改时间:2022-04-19
    inline void HistoryAdd(const T& Item, bool bRemoveLast)
    {
        if (_Count == 0) {
            Add(Item);
        }
        else if (_Count == 1) {
            if (bRemoveLast) {
                _First->Data = Item;
            }
            else {
                //把无素放在最前
                _DListNode<T>* dnNew = _Memory::New<_DListNode<T>>(1);
                dnNew->Data = Item;
                _First->Prev = dnNew;
                dnNew->Next = _First;
                _First = dnNew;
                ++_Count;
            }
        }
        else {
            if (bRemoveLast) {
                _DListNode<T>* dnDelete = _Last;

                //删除最后一个元素
                _Last = _Last->Prev;
                _Last->Next = null;

                _DListNode<T>* dnNew = _Memory::New<_DListNode<T>>(1);
                dnNew->Data = Item;

                _First->Prev = dnNew;
                dnNew->Next = _First;
                dnNew->Prev = null;

                _First = dnNew;

                _Memory::Delete< _DListNode<T>>(dnDelete, 1);
            }
            else {
                //把无素放在最前
                _DListNode<T>* dnNew = _Memory::New<_DListNode<T>>(1);
                dnNew->Data = Item;

                _First->Prev = dnNew;
                dnNew->Next = _First;
                dnNew->Prev = null;

                _First = dnNew;

                ++_Count;
            }
        }
    }

    /// <summary>
    /// 出栈(先进后出),删除最后一个元素,
    /// </summary>
    /// 创建时间: 2022-04-19      最后一次修改时间:2024-10-01
    inline void StackPop(){         
    
        if (_Last == null || _Count == 0) {

            throw "没有元素可删!";
        }
        
        auto tmp = _Last;

        _Last = _Last->Prev;
        _Last->Next = null;

        m.Delete<_DListNode<T>>(tmp,1);

        --_Count;             
    }

    //----------------------------------------------------------------------------------------------------Python List方法
     

    /// <summary>
    /// 将元素tItem添加到列表末尾。
    /// </summary>
    /// 创建时间: 2023-04-08      最后一次修改时间:2023-04-08
    inline void Python_append(const T& tItem)
    {
        Add(tItem);
    }

     

    /// <summary>
    /// 在位置nIndex后面插入一个元素tItem
    /// </summary>
    inline void Python_insert(const size_t  &nIndex, const T& tItem)
    {
        InserNodeBack(IndexOfNode(nIndex), tItem);
    }
      
    /// <summary>
    /// 在最前面插入一项
    /// </summary>
    /// <param name="tItem"></param>
    /// 创建时间: 2024-04-16      最后一次修改时间:2024-09-19
    inline void inseart_front(const T& tItem){

        this->SortOrder = _SortOrder::s_null;

        _DListNode<T>* pNode = _Memory::New<_DListNode<T>>(1);
        pNode->Data = tItem;

        if (_First != null){

            _First->Prev = pNode;

            pNode->Next = _First;
            pNode->Prev = null;

            _First = pNode;
        }else{ 

            pNode->Next = null;
            pNode->Prev = null;

            _First = pNode;
            _Last = pNode;
        }

        ++_Count;
    }
 

    inline _DListNode<T>* inseart_back(_DListNode<T>* pNode, const T& tData) {
        return this->InserNodeBack(pNode, tData);
    }

    inline _DListNode<T>* inseart_front(_DListNode<T>* pNode, const T& tData) {
        return this->InserNodeFront(pNode, tData);
    }

   
    /// <summary>
    /// 删除索引位置为nIndex的元素,并返回删除的元素值的拷贝,如果索引值nIndex = -1,则默认删除为最后一个元素。
    /// </summary>
    /// <param name="nIndex"></param>
    /// <returns></returns>
    /// 创建时间: 2023-04-08      最后一次修改时间:2023-04-09
    inline T Python_pop(const size_t nIndex = npos)
    {
        
        if (nIndex == npos)
        {         
            return StackPop();
        }
        else
        { 
            auto dn = this->IndexOfNode(nIndex);

            T tmp = T();

            if (dn != null)
            {
                tmp = dn->Data;                  

                DeleteNode(dn);
            }

            return tmp;
        }         
    }

     
    /// <summary>
    /// 删除值为tItem的一项。
    /// 注意,方法remove()只删除第一个指定的值。如果要删除的值可能在列表中出现多次,
    /// 就需要使用循环来确保每个值都删除。
    /// </summary>
    inline bool Python_remove(const T& tItem)
    { 
        int n = _Count;

        DeleteNode(FindNodeItem(tItem));

        return n == _Count;
    }



protected:

    /// <summary>
    /// 删除链表中的节点
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="pListItem"></param>
    /// <returns></returns>
    //inline bool DeleteNode(const _DListNode<T>* pNodeDelete)
    //{
    //    if (_Count == 0 || pNodeDelete == null)
    //    {
    //        return false;
    //    }

    //    _DListNode<T>* pNode = _First.Next;

    //    while (pNode != null)
    //    {
    //        if (pNode == pNodeDelete)  //找到了
    //        {
    //            //pListItem->Prev

    //            if (pNodeDelete->Prev != null)
    //            {
    //                pNodeDelete->Prev->Next = pNodeDelete->Next;
    //            }
    //            else //删除的是第一个节点
    //            {
    //                _First = pNodeDelete.Next;
    //            }


    //            //pListItem->Next

    //            if (pNodeDelete->Next != null)
    //            {
    //                pNodeDelete->Next->Prev = pNodeDelete->Prev;
    //            }
    //            else //删除的是最后一个节点
    //            {
    //                _Last = pNodeDelete->Prev;
    //            }

    //            break;
    //        }

    //        pNode = pNode->Next;
    //    }

    //    if (pNode != null)
    //    {
    //        --_Count;

    //        _Memory::Delete< _DListNode<T> >(pNode,1);  //C#不用清除内存

    //        return true;
    //    }

    //    return false;

    //}

  
    
    /// <summary>
    /// 删除链表中的某一节点,注意,这个节点一定要是在链表中的,
    /// 并返回当前要删除节点所指的下一节点。
    /// </summary>
    /// 创建时间: 2023-04-09      最后一次修改时间:2024-09-26
    inline _DListNode<T>* DeleteNode(_DListNode<T>* pNodeDelete, bool isCheck = false)
    {
        if (isCheck) {

            if (this->FindNodeIndex(pNodeDelete) == -1) {

                throw std::exception("节点不在链接上");               
            }
        }


        if (_Count == 0 || pNodeDelete == null) return NULL;

        auto pResultNode = pNodeDelete->Next;

        if (_Count == 1)
        {     
            ClearMemory();
        }
        else
        {
            if (pNodeDelete == _First) //删除的是第一个节点
            {
                _First = _First->Next;
                _First->Prev = null;
            }
            else if (pNodeDelete == _Last)
            {
                _Last = _Last->Prev;
                _Last->Next = null;
            }
            else
            {
                pNodeDelete->Prev->Next = pNodeDelete->Next;
                pNodeDelete->Next->Prev = pNodeDelete->Prev;

            }

            --_Count;
            _Memory::Delete< _DListNode<T> >(pNodeDelete, 1);
        }

        return pResultNode;
    }



public: //------------------------------------------------------------------重写


 
    /// <summary>
    /// 转换为字符串
    /// </summary>
    /// <returns></returns>
    /// 创建时间: 2023-05-16      最后一次修改时间:2024-07-23
    inline virtual  _string ToSplitString(const _string& sSplitString)  const override
    {
        //不可以这样: const _DList<_Object>* dp = (_DList<_Object> *)pList;
        //就算 T 类型数据是从 _Object中继承也不可以。


 
        _string sResult;

        sResult.Add(_t("{"));

        _string sp = sSplitString.Length == 0 ? _string(_t(",")) : sSplitString;


        if(_Count > 0){

            //是否继承处_Object
            if (std::is_base_of<_Object, T>::value)
            {  
                _Object* po;

                if (_Count == 1)
                {
                    po = (_Object*)(&_First->Data);

                    sResult.Add((_string)(*po));
                }

                _DListNode<T>* dn = this->_First;
                while (dn != _Last)
                {
                    po = (_Object*)(&dn->Data);

                    sResult.Add((_string)(*po));
                    sResult.Add(sp);

                    dn = dn->Next;
                }
                po = (_Object*)(&_Last->Data);


                sResult.Add((_string)(*po));
            }
            else
            {

                if (typeid(T) == typeid(int))
                {
                    _DListNode<T>* dn = this->_First;
                    while (dn != _Last)
                    {
                        int* pInt = (int*)&(dn->Data);
                        sResult.Add(_string::Java_valueOf(*pInt));
                        sResult.Add(sp);

                        dn = dn->Next;
                    }

                    if (this->Count > 0)
                        sResult.Add(_string::Java_valueOf(*((int*)(&(_Last->Data)))));
                }         
                else if(typeid(T) == typeid(size_t))
                {
                    _DListNode<T>* dn = this->_First;
                    while (dn != _Last)
                    {
                        size_t* pInt = (size_t*)&(dn->Data);
                        sResult.Add(_string::Java_valueOf(*pInt));
                        sResult.Add(sp);

                        dn = dn->Next;
                    }

                    if (this->Count > 0)
                        sResult.Add(_string::Java_valueOf(*((size_t*)(&(_Last->Data)))));
                }
                else if (typeid(T) == typeid(double))
                {
                    if (_Count == 0) return sResult;

                    double* pd;

                    if (_Count == 1)
                    {
                        pd = (double*)(&(_First->Data));

                        sResult.Add(_Convert::DoubleToString(*pd));
                    }

                    _DListNode<T>* dn = this->_First;
                    while (dn != _Last)
                    {
                        pd = (double*)&(dn->Data);
                        sResult.Add(_Convert::DoubleToString(*pd));
                        sResult.Add(sp);

                        dn = dn->Next;
                    }
                    pd = (double*)&(_Last->Data);
                    sResult.Add(_Convert::DoubleToString(*pd));
                }
                else if (typeid(T) == typeid(_string))
                {
                    _string* ps;

                    _DListNode<T>* dn = this->_First;
                    while (dn != _Last)
                    {
                        ps = (_string*)(&dn->Data);

                        sResult.Add(_t("\""));
                        sResult.Add(*ps);
                        sResult.Add(_t("\""));
                        sResult.Add(sp);
                        dn = dn->Next;
                    }

                    if (_Count > 0)
                    {
                        ps = (_string*)(&_Last->Data);
                        sResult.Add(_t("\""));
                        sResult.Add(*ps);
                        sResult.Add(_t("\""));
                    }
                }
                else if (typeid(T) == typeid(_StrA))
                {
                    _StrA* ps;

                    if (_Count <= 0)
                    {
                    }
                    else if (_Count == 1)
                    {
                        ps = (_StrA*)(&_First->Data);

                        sResult.Add(_t("\""));
                        sResult.Add(*ps);
                        sResult.Add(_t("\""));
                    }
                    else
                    {
                        _DListNode<T>* dn = this->_First;
                        while (dn != _Last)
                        {
                            ps = (_StrA*)(&dn->Data);

                            sResult.Add(_t("\""));
                            sResult.Add(*ps);
                            sResult.Add(_t("\""));
                            sResult.Add(_t(','));

                            dn = dn->Next;
                        }
                        ps = (_StrA*)(&_Last->Data);

                        sResult.Add(_t("\""));
                        sResult.Add(*ps);
                        sResult.Add(_t("\""));
                    }
                }
                else if (typeid(T) == typeid(std::string)) {

                    std::string* ps;

                    if (_Count <= 0)
                    {
                    }
                    else if (_Count == 1)
                    {
                        ps = (std::string*)(&_First->Data);

                        sResult.Add(_t("\""));
                        sResult.Add(_string(ps->c_str()));
                        sResult.Add(_t("\""));
                    }
                    else
                    {
                        _DListNode<T>* dn = this->_First;
                        while (dn != _Last)
                        {
                            ps = (std::string*)(&dn->Data);

                            sResult.Add(_t("\""));
                            sResult.Add(_string(ps->c_str()));
                            sResult.Add(_t("\""));
                            sResult.Add(_t(','));

                            dn = dn->Next;
                        }
                        ps = (std::string*)(&_Last->Data);

                        sResult.Add(_t("\""));
                        sResult.Add(_string(ps->c_str()));
                        sResult.Add(_t("\""));
                    }
                }
                else  //所有继承自 _Object 类的数据类型都可以
                {

                    sResult.Add(_t("_LDList::ToSplitString重写,数据类型为:"));
                    sResult.Add(_string(typeid(T).name()));            


                }
            }

        }

        sResult.Add(_t("}"));

        return sResult;
  
    }

    inline _string ToString()const
    {
        return ToSplitString(_t(""));
    }

    //

                      //下面设计都是为了兼容  std 标准库

    
 
    //----------------------------------------------------------  C++
 

    inline void std_push_back(const T& tItem) { Add(tItem); }
    inline void push_back(const T& tItem) { std_push_back(tItem); }

    inline void std_push_front(const T& tItem) { this->inseart_front(tItem); }
    inline void push_front(const T& tItem) { std_push_front(tItem); }

    /// <summary>
    /// 在_Where位置前插入[itBegin,itEnd)(用法与std::list::insert要一样)
    /// 注意:std旧重版itBegin和itEnd不能指向与目的位置相同的容器,在新标准版可以。
    /// </summary>
    /// <typeparam name="IteratorClass"></typeparam>
    /// <param name="_Where"></param>
    /// <param name="itBegin"></param>
    /// <param name="itEnd"></param>
    /// 创建时间: 2024-09-22      最后一次修改时间:2024-09-22 (已测试)
    template<class IteratorClass>
    inline _DListNodeIterator<T> std_insert(const _DListNodeIterator<T>& _Where, const IteratorClass& itBegin,
        const IteratorClass& itEnd) {

        /*
            list slist;      
            //运行时错误:迭代器表示要拷贝的范围,不能指向与目的位置相同的容器
            slist.insert(slist.begin(),slist.begin(),slist.end());
       
        */

        if (typeid(_DListNodeIterator<T>) == typeid(IteratorClass)) {

            _DListNodeIterator<T>* pbegin = (_DListNodeIterator<T>*)(&itBegin);
            _DListNodeIterator<T>* pend = (_DListNodeIterator<T>*)(&itEnd);

            //lassert(_Where._pCurrentList != p->_pCurrentList,"不能插入指向相同容器的元素");
            if (_Where._pCurrentList == pbegin->_pCurrentList) {

                //创建一个临时链表,会影响性能
                _DList<T> tmp(*pbegin,*pend);
                return std_insert(_Where, tmp.begin(), tmp.end());
            }            
        }     

        IteratorClass tmp = itBegin;

        _DListNode<T>* pReulst = null;

        if (_Where._Ptr == null) {

            while (tmp != itEnd) {

                if (pReulst == null) {
                    //保存第一次插入的结点,以便返回
                    pReulst = this->inseart_back(_Last, *tmp);
                }
                else
                    this->inseart_back(_Last, *tmp);
                ++tmp;
            }

        }
        else {

            auto ptr = _Where._Ptr;

            while (tmp != itEnd) {
                if (pReulst == null) //第一次,在前面插入第一项
                {
                    ptr = this->inseart_front(ptr, *tmp);
                    //保存第一次插入的结点,以便返回

                    pReulst = ptr;
                }
                else { //第二次开始,在插入的第一项后面依次插入
                    ptr = this->inseart_back(ptr, *tmp);
                }

                ++tmp;
            }
        }

        return _DListNodeIterator<T>(pReulst, this);
    }

    template<class IteratorClass>
    inline _DListNodeIterator<T> insert(const _DListNodeIterator<T>& _Where, 
        const IteratorClass& itBegin,const IteratorClass& itEnd) {
        return std_insert(_Where, itBegin, itEnd);
    }






    /// <summary>
    /// std::insert
    /// </summary>
    /// <param name="_Where"></param>
    /// <param name="_Ilist"></param>
    /// <returns></returns>
    /// 创建时间: 2024-09-22      最后一次修改时间:2024-09-22 (已测试)
    inline _DListNodeIterator<T> std_insert(const _DListNodeIterator<T>& _Where,
        std::initializer_list<T> _Ilist) {
        return std_insert(_Where, _Ilist.begin(), _Ilist.end());
    }

    inline _DListNodeIterator<T> insert(const _DListNodeIterator<T>& _Where,
        std::initializer_list<T> _Ilist) {
        return std_insert(_Where, _Ilist.begin(), _Ilist.end());
    }

    /// <summary>
    /// boject.insert(p,t)	 boject.emplace(p, args)
    /// 在迭代器p指向的元素之前创建一个值为t或由args创建的元	素。
    /// 返回指向新添加的元素的迭代器
    /// </summary>
    /// <param name="_Where"></param>
    /// <param name="tValue"></param>
    /// <returns></returns>
    /// 创建时间: 2024-09-22      最后一次修改时间:2024-09-22  (已测试)
    inline _DListNodeIterator<T> std_insert(const _DListNodeIterator<T>& _Where, const T& tValue) {
        if (_Where._Ptr == null)
            return _DListNodeIterator<T>(inseart_back(_Last, tValue), this);
        else
            return _DListNodeIterator<T>(inseart_front(_Where._Ptr, tValue), this);
    }

    inline _DListNodeIterator<T> insert(const _DListNodeIterator<T>& _Where, 
        const T& tValue) {
        return std_insert(_Where, tValue);
    }


    /// <summary>
    /// boject.insert(p,t)	 boject.emplace(p, args)
    /// 在迭代器p指向的元素之前创建一个值为t或由args创建的元	素。
    /// 返回指向新添加的元素的迭代器
    /// </summary>
    /// <typeparam name="...args"></typeparam>
    /// <param name="it"></param>
    /// <param name="..._Val"></param>
    /// <returns></returns>
    template<class... ArgsTypes>
    inline _DListNodeIterator<T> std_emplace(const _DListNodeIterator<T>& it,
        ArgsTypes&&... args) {        
        return this->std_insert(it, T(std::forward<ArgsTypes>(args)...));
    }

    template<class... ArgsTypes>
    inline _DListNodeIterator<T> emplace(const _DListNodeIterator<T>& it,
        ArgsTypes&&... args) {
        return  std_emplace(it, args...);
    }


    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="..._Valty"></typeparam>
    /// <param name="..._Val"></param>
    /// <returns></returns>
    /// 创建时间: 2024-09-23      最后一次修改时间:2024-09-23  (已测试)
    template <class... ArgsTypes>
    const _DListNodeIterator<T> std_emplace_front(ArgsTypes&&... args) {

        return this->_DListNodeIterator<T>(
            inseart_front(T(std::forward<ArgsTypes>(args)...)),
            this);         
    } 

    template <class... ArgsTypes>
    const _DListNodeIterator<T> emplace_front(ArgsTypes&&... args) {

        return std_emplace_front(args...);
    }


    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="..._Valty"></typeparam>
    /// <param name="..._Val"></param>
    /// <returns></returns>
    /// 创建时间: 2024-09-23      最后一次修改时间:2024-09-23  (已测试)
    template <class... ArgsTypes>
    const _DListNodeIterator<T> std_emplace_back(ArgsTypes&&... args) {

        return this->_DListNodeIterator<T>(
            inseart_back(T(std::forward<ArgsTypes>(args)...)),
            this);
    }

    template <class... ArgsTypes>
    const _DListNodeIterator<T> emplace_back(ArgsTypes&&... args) {

        return std_emplace_back(args...);
    }

    /// <summary>
    /// 包括array在内的每个顺序容器都有一个front成员函数,而除forward_list
    /// 之外的所有顺序容器都有一个back成员函数。这两个函操作分别返回函数首元
    /// 素和尾元素的引用
    ///  	在容器中访问元素的成员函数(即,front,back、下标和at)返回的都是引用。
    /// 如果容器是一个const对象,则返回值是const的引用。如果容器不是const的,则
    /// 返回值是普通引用,我们可以用来改变元素的值
    /// </summary>
    /// <returns></returns>
    /// 创建时间: 2024-09-25      最后一次修改时间:2024-09-25   
    inline const T& std_front()const {
        //标准库不做检查
        lassert(this->_Count > 0 && _Count != 0);

        return _First->Data;
    }

    inline T& std_front() {
        //标准库不做检查
        lassert(this->_Count > 0 && _Count != 0);

        return _First->Data;
    }

    inline const T& front()const { return std_front(); }
    inline  T& front() { return std_front(); }

    /// <summary>
    ///     包括array在内的每个顺序容器都有一个front成员函数,而除forward_list
    /// 之外的所有顺序容器都有一个back成员函数。这两个函操作分别返回函数首元
    /// 素和尾元素的引用
    ///  	在容器中访问元素的成员函数(即,front,back、下标和at)返回的都是引用。
    /// 如果容器是一个const对象,则返回值是const的引用。如果容器不是const的,则
    /// 返回值是普通引用,我们可以用来改变元素的值
    /// </summary>
    /// <returns></returns>
    /// 创建时间: 2024-09-25      最后一次修改时间:2024-09-25   
    inline const T& std_back()const {
        lassert(this->_Count > 0);
        return _Last->Data;
    }

    inline  T& std_back() {
        lassert(this->_Count > 0);
        return _Last->Data;
    }

    inline const T& back()const {  return std_back();}
    inline  T& back() { return std_back(); }

    /// <summary>
    /// 返回下标为n的元素的引用。如果下标越界,则抛出-out_of_range异常
    ///  	在容器中访问元素的成员函数(即,front,back、下标和at)返回的都是引用。
    /// 如果容器是一个const对象,则返回值是const的引用。如果容器不是const的,则
    /// 返回值是普通引用,我们可以用来改变元素的值
    /// </summary>
    /// <param name="nIndex"></param>
    /// <returns></returns>
    /// 创建时间: 2024-09-26      最后一次修改时间:2024-09-26   
    inline const T& std_at(const size_t& nIndex)const { return (*this)[nIndex]; }
    inline  T& std_at(const size_t& nIndex) { return (*this)[nIndex]; }

    inline const T& at(const size_t& nIndex)const { std_at(nIndex); }
    inline  T& at(const size_t& nIndex){ return std_at(nIndex); }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    /// 创建时间: 2024-09-25      最后一次修改时间:2024-09-25   
    inline bool std_empty() { return _Count == 0; }
    inline bool empty() { return std_empty(); }

    inline  _DListNodeIterator<T> std_begin()const { return _DListNodeIterator<T>(_First, this); }
    inline auto begin()const { return std_begin(); }

    inline _DListNodeReverseIterator<T>  std_rbegin()const { return _DListNodeReverseIterator<T>(_Last, this); }
    inline  auto rbegin()const { return std_rbegin(); }


    inline _DListNodeIterator<T>  std_end()const {
        
        //迭代器使用的语句
        //for (_DListNodeIterator<int> f = dl.begin(); f != dl.end(); f++) {       }
        return _DListNodeIterator<T>(null, this);
    }

 
    inline auto end()const { return std_end(); }

    inline _DListNodeReverseIterator<T>  std_rend()const {

        //迭代器使用的语句
        //for (_DListNodeIterator<int> f = dl.begin(); f != dl.end(); f++) {       }

        return _DListNodeReverseIterator<T>(null, this);    
    }

         
    inline auto rend()const{  return std_rend(); }



    /// <summary>
    /// 
    /// </summary>
    /// <param name="itFrist"></param>
    /// <param name="itLast"></param>
    /// <returns></returns>
    /// 创建时间: 2024-09-25      最后一次修改时间:2024-09-25   
    _DListNodeIterator<T> std_erase(const _DListNodeIterator<T>& itFrist,
        const _DListNodeIterator<T>& itLast){

        auto pNode = itFrist._Ptr;
        
        while (pNode != itLast._Ptr && pNode != null) {

            pNode = this->DeleteNode(pNode);
        }

        return itLast;
    }


    /// <summary>
    /// 
    /// </summary>
    /// <param name="itFrist"></param>
    /// <param name="itLast"></param>
    /// <returns></returns>
    /// 创建时间: 2024-09-25      最后一次修改时间:2024-09-25  
    _DListNodeIterator<T> erase(const _DListNodeIterator<T>& itFrist,
        const _DListNodeIterator<T>& itLast) {
        return std_erase(itFrist, itLast);
    }


    /// <summary>
    /// 
    /// </summary>
    /// <param name="it"></param>
    /// <returns></returns>
    /// 创建时间: 2024-09-25      最后一次修改时间:2024-09-25  
    _DListNodeIterator<T> erase(const _DListNodeIterator<T>& it) {

        return _DListNodeIterator<T>(DeleteNode(it._Ptr), this);

    }


    /// <summary>
    /// 
    /// </summary>
    /// <param name="nCount"></param>
    /// <param name="defaultValue"></param>
    /// 创建时间: 2024-10-01      最后一次修改时间:2024-10-01 
    void std_resize(const size_t& nCount, const T& defaultValue) {
               
        if (this->_Count < nCount) { //添加

            for (size_t n = _Count;  n < nCount; ++n) {
                Add(defaultValue);
            }

        }else { //删除
            size_t nDelete = _Count - nCount;

            for (size_t n = 0; n < nDelete; ++n) {
                StackPop();
            }
        }        
    }


    /// <summary>
    /// resize操作授受一个可选的元素值参数,用来初始化添加到容器中的元素。
    /// 如果调用者未提供此参数,新元素进行值初始化,如果容器保存的是类类
    /// 型元素,且resize向容器添加新元素,则我们必须提供初始值,或者元素
    /// 类型必须提供一个默认构造函数。
    /// </summary>
    /// <param name="nCount"></param>
    /// <param name="defaultValue"></param>
    void resize(const size_t& nCount, const T& defaultValue = T()) 
    { std_resize(nCount, defaultValue); }



}; //--------------------------------------------------------------------------DList

 
 


//


                                //SortedDList



//

/// <summary>
///  C#语句:public class SortList<T> : _DList<T>
/// </summary>
/// <typeparam name="T"></typeparam>
template<class T>
class SortedDList : public _DList<T>
{


};


//


                                //_StrList



// 
template<class T>
class _StrList : public _DList<T>
{

public:  
    //------------------------------------------------------------------构造与析构 

    _StrList() : _DList<T>() {};

    _StrList(const _StrList<T>& sl) : _DList<T>(sl) {};

    explicit _StrList(const _char* pStr, const _char* pSplit, bool bIgnoreEmptyString = false)
    {
        this->InitData();
        SplitForSeparator(pStr, pSplit, bIgnoreEmptyString);
         
    }


    /// <summary>
    /// 要加上 explicit阻止自动转换, 否则执行语名会自动调用这个构造函数  _StrList  ls = { L"AA",L"BB"};
    /// </summary>
    /// <param name="sText"></param>
    /// <param name="sSplit"></param>
    /// <param name="bIgnoreEmptyString"></param>
    explicit _StrList(const T& sText, const T& sSplit, bool bIgnoreEmptyString = false)
    {
        //assert(sText != null && sSplit != null);

        //SplitForSeparator(sText.Data, sSplit.Data, bIgnoreEmptyString);
         
        if (sText.Length == 0) { return; }


        if (sSplit.Length == 0) { Add(sText);   return; }


        int iStart = 0;
        int iIndex = sText.IndexOf(sSplit, iStart);

        if (iIndex == -1)
        {
            Add(sText);
            return;
        }



        while (iIndex != -1 && iStart + 1 <= sText.Length)
        {
            if (iIndex != iStart)
                Add(sText.SubStr(iStart, iIndex - iStart));
            else
            {
                if (!bIgnoreEmptyString) Add(T());
            }
            iStart = iIndex + sSplit.Length;

            iIndex = sText.IndexOf(sSplit, iStart);

            if (iIndex == -1 && sText.Length != iStart)
                Add(sText.SubStr(iStart, sText.Length - iStart));  //拷贝最后一个
        }
       
    }



    _StrList(std::initializer_list<T> aList)
    {
        for (T s : aList)
        {
            Add(s);
        }
    }

public: 
     
    
    //------------------------------------------------------------------操作

    void writeToFile(const T& sFullPathName)
    {
         
    }


    bool readToFile(const T& sFullPathName)
    {
        return false;
    }


    bool readToUnicodeFile(const T& sFileName, const T& sSplit)
    {
        return false;
    }


    /// <summary>
    /// 获取所有字符串的总共长度
    /// </summary>
    /// <returns></returns>
    /// 创建时间:  2022-11-05    最后一次修改时间:  2022-11-05 
    int GetStringLength() const
    {
        int iSum = 0;

        auto dn = this->_First;

        while (dn != null) {
            iSum += (int)dn->Data.Length;
            dn = dn->Next;
        }

        return iSum;
    }


    T connectForSeparator(const T& sConnector)const
    {
        if (this->_Count == 0) return _t("");

        if (this->_Count == 1) return this->_First->Data;

        T tmp(_t(""), GetStringLength() + sConnector.Length * this->_Count + 100);

        _DListNode<T>* ldNode = this->_First;

        while (ldNode != this->_Last)
        {
            tmp += ldNode->Data;
            tmp += sConnector;
            ldNode = ldNode->Next;
        }


        tmp += this->_Last->Data;       //加入最后一项

        return tmp;
    }

    T connectForSeparator(const _char& cConnector) const
    {
        return connectForSeparator(&cConnector);
    }




    /// <summary>
    /// 返回分隔后的字符串列表
    /// </summary>
    /// <param name="pStr">原文本</param>
    /// <param name="pSplit">分隔字符串</param>
    /// <param name="bIgnoreEmptyString">是否忽略空字符串</param>
    /// <returns>返回一个字符串列表</returns>
    /// 创建时间: 2022-10-04     最后一修改时间:2022-10-05       已测试
    _StrList<T>& SplitForSeparator(const _char* pStr, const _char* pSplit, bool bIgnoreEmptyString)
    {

        if (pStr == null || pSplit == null)
        {
            _cout << "在中_StrList::SplitForSeparator中" << L"pStr == null || pSplit == null" << "\n";

            throw "pStr == null || pSplit == null";
        }


        this->ClearData();

        if (pStr[0] == 0 || pSplit[0] == 0)
        {
            Add(_t(""), 0, 0);
            return *this;
        }


        int i = 0;
        int j = 0;

        int nStart = 0, nEnd = 0;

        while (pStr[i] != 0) {

            // _cout << _t("pStr[i] = ") << pStr[i] << _t("\n");  //此句出错,无任何提示

            bool bFind = true;

            j = 0;
            while (pSplit[j] != 0) {

                if (pStr[i + j] != pSplit[j]) {
                    bFind = false;
                    break;
                }
                ++j;
            }

            if (bFind) {
                nEnd = i - 1;     //此处如果 nEnd 是 int ,则 nEnd = i - 1 => nEnd = 18446744073709551615 => 溢出错误 
                if (bIgnoreEmptyString) {
                    if (nStart <= nEnd) {
                        Add(pStr, nStart, nEnd);  //这里应nStart <= nEnd,而不是 nStart < nEnd,因为当 nStart = nEnd 还是有一个字符的
                    }
                }
                else {
                    Add(pStr, nStart, nEnd);
                }

                nStart = i + j;

                i = nStart - 1;
            }
            ++i;
        }



        //拷贝右边最后一项
        if (bIgnoreEmptyString) {
            if (nStart <= i - 1) {
                Add(pStr, nStart, (int)i - 1);
            }
        }
        else {
            Add(pStr, nStart, (int)i - 1);
        }

        return *this;
    }

    //int SplitForSeparator(const T& sText, const _char& cSplit);

    int IndexOf(const T& s)
    {
        int nIndex = 0;

        auto dn = this->_First;

        while (dn)
        {

            if (dn->Data == s) { return nIndex; }

            ++nIndex;

            dn = dn->Next;
        }

        return -1;
    }


    int GetMaxSpaceLength(int nTabCount = 9, int nChineseCharactersCount = 3)const
    {
        int nMax = 0;

        auto dn = this->_First;

        while (dn)
        {
            int n = gs.s_length_space(dn->Data.Data, nTabCount, nChineseCharactersCount);

            if (n > nMax) nMax = n;

            dn = dn->Next;
        }
        return nMax;
    }
 



    /// <summary>
    /// 用tab键使每行等长
    /// </summary>
    /// <param name="nTabCount"></param>
    /// <returns></returns>
    /// 创建时间:  2022-10-30    最后一次修改时间:  2022-10-30 
    T equilongTabLine(int nTabCount = 9)
    {
        this->RemoveHeadTab();

        int iMax = GetMaxSpaceLength(nTabCount);

        for (T& s : *this) {
            int nSapceLength = gs.s_length_space(s.Data);
            int n = (iMax - nSapceLength) / 9;

            if (iMax - nSapceLength - n * 9 >= 5)
                ++n;
            else
                --n;

            for (int j = 0; j < n; j++)
            {
                s.Add(_t("\t"));
            }
        }


        return connectForSeparator(_t('\n')) + _t('\n');
    }


    /// <summary>
    /// 计算所有行,如果每行都有开始处都有 \t ,则每行除去 \t , 除去个数以最少 \t 行为准。
    /// 例:
    /// \t\t abc
    /// \t bcd
    /// \t\t\t dd
    /// 运行函数后变成
    /// \t abc
    /// bcd
    /// \t\t dd
    /// </summary>
    /// 创建时间:  2022-11-05    最后一次修改时间:  2022-11-05 
    void RemoveHeadTab()
    {
        int iMin = 100000000;

        for (T& s : *this) {

            if (s.Length > 0)
            {
                int iCount = gs.s_headTabCount(s.Data);
                if (iCount < iMin) { iMin = iCount; }

                //log::d("iCount=" + iCount.ToString(), s);
            }
        }

        //log::d("iMin=" + iMin.ToString());

        if (iMin > 0)
        {
            for (T& s : *this) {
                s = s.SubStr(iMin, s.Length - iMin);
            }
        }
    }

    //-----------------------------------------------------------------------虚函数
    virtual _DListNode<T>* Add(const T& item) override
    {
        //_cout << item << "\n";
        return _DList<T>::Add(item);
    }



    void Add(const _StrList<T>& ls)   //覆盖 父类重载函数 virtual bool Add(const T& item);
    {
        _DListNode<T>* pNode = ls._First;

        while (pNode != null)
        {
            Add(pNode->Data);
            pNode = pNode->Next;
        }
    }


    /// <summary>
    /// 添加拷贝nStartPos和nEndPos之间的字符,包括nStartPos和nEndPos。
    /// </summary>
    /// <param name="str"></param>
    /// <param name="nStartPos"></param>
    /// <param name="nEndPos"></param>
    /// <returns></returns>
    /// 创建时间:  ????-??-??   最后一次修改时间:????-??-??   已测试(2024-08-16 )
    bool Add(const T& str, int nStartPos, int nEndPos)
    {
        if (str.Length == 0 || nEndPos - nStartPos < 0)
        {
            Add(T());
        }
        else {
            int nLength = nEndPos - nStartPos + 1;

            /*
            _Mem<_char> m(nLength + 1);

            for (int i = 0; i < nLength; ++i)
            {
                m.Data[i] = pStr[nStartPos + i];

            }

            m.Data[nLength] = 0;
            */
            Add(str.SubStr(nStartPos, nLength));
        }

        return false;
    }
 

    _string  ToSplitString(const _string& sSplitString) const  override
    {
        /*
        *  auto dn = this->_First;

        T sResult;
  
        while (dn != this->_Last)
        {           
            sResult.std_append(dn->Data);                          
            
            sResult.std_append(sConnector);

            dn = dn->Next;
        }

        if (this->_Last != null)
        {
            sResult.std_append(dn->Data);
        }

        char c = '\n';

        sResult.std_append(c );

        return sResult;
        */
        return _DList<T>::ToSplitString(sSplitString);
    }
};

//


                                //_UStrList



// 
/// <summary>
/// 不重复的字符串列表
/// </summary>
/// <typeparam name="T"></typeparam>
/// 创建时间: 2023-05-11      最后一次修改时间:2023-05-11
template<class T>  
class _UStrList : public _StrList<T>
{ 
public:
    /// <summary>
    /// 加入一个串,如果这个串存在,则把这项移到最后。
    /// </summary>
    /// <param name="item"></param>
    /// 创建时间: ????-??-??      最后一次修改时间:2024-09-23 (已测试)
    _DListNode<T>* Add(const T& item)override
    {  
        bool bFind = false;
        _DListNode<T>* dnTemp = this->_First;
        while (dnTemp != null)
        {
            if (dnTemp->Data == item){
               
                return this->MoveLast(dnTemp);             
            }
            dnTemp = dnTemp->Next;
        }

        return _StrList<T>::Add(item);       
    }
  
};

//


                                //_UStrListCI



// 
/// <summary>
/// 值都是唯一的字符串列表,  Case Insensitive(不区分大小写)
/// </summary>
template<class T>
class _UStrListCI : public _StrList<T>
{

public:
    /// <summary>
    /// 加入一个串,如果这个串存在,则把这项移到最后。
    /// </summary>
    /// <param name="item"></param>
    /// 创建时间: ????-??-??      最后一次修改时间:2024-09-23
    _DListNode<T>* Add(const T& item)override
    {
        bool bFind = false;
        _DListNode<T>* dnTemp = this->_First;
        while (dnTemp != null)
        {
            if (dnTemp->Data.csharp_ToLower() == item.csharp_ToLower())
            {
                return this->MoveLast(dnTemp);
            }
            dnTemp = dnTemp->Next;
        }

        return _StrList<T>::Add(item);    
    }

  

    /*

    /// <summary>
    /// 返回前面一个值
    /// </summary>
    /// <param name="tCurrValue"></param>
    /// <returns></returns>
    T& GetForward(T& sCurr)
    {
        int iIndex = BinarySearch(sCurr);
        if (iIndex != -1)
        {
            if (iIndex + 1 < _Count)
                return this[iIndex + 1];
        }
        return null;
    }

    /// <summary>
    /// 返回后面的一个值
    /// </summary>
    /// <param name="sCurr"></param>
    /// <returns></returns>
    T& GetBack(T& sCurr)
    {
        int iIndex = BinarySearch(sCurr);
        if (iIndex != -1)
        {
            if (iIndex - 1 < _Count && iIndex - 1 >= 0)
                return this[iIndex - 1];
        }
        return null;
    }

    */
};


//


                                //_SStrList



// 
/// <summary>
/// 已排序好的字符串列表
/// </summary>
template<class T>
class _SStrList : public  _StrList<T>
{
public:
    _SStrList(const _SortOrder so = _SortOrder::s_Minmax)
    {

        this->_so = so;

        if (this->_so == _SortOrder::s_null)
        {
            throw  _t("排序不能为空!");
        }
    }


    //-------------------------------------------------------------------------------重写

    /// <summary>
    /// 快速添加字符串,差不多用了8个小时(两天),才写成。
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    bool Add(const T& item) override
    {
        if (this->_Count < 3)
        {
            bool bInsert = false;
            _DListNode<T>* ld = this->_First;

            while (ld != null)
            {
                if (this->_so == _SortOrder::s_Maxmin)
                {
                    if (item >= ld->Data)
                    {

                        _StrList<T>::InserNodeFront(ld, item); bInsert = true;
                        break;
                    }
                }
                else
                {
                    if (item <= ld->Data)
                    {
                        _StrList<T>::InserNodeFront(ld, item); bInsert = true; break;
                    }
                }
                ld = ld->Next;
            }
            if (!bInsert) _StrList<T>::Add(item);
            return true;
        }

        int nPos = this->_Count / 2;   //nPos在中间,所以无素一定要大于等于3才行
        int nLeft = 0;   //左边远素
        int nRight = this->_Count - 1;  //右边远素

        if (this->_so == _SortOrder::s_Maxmin)
        {
            _DListNode<T>* ld = null;

            while (nRight >= 0 && nLeft >= 0)
            {
                ld = this->IndexOfNode(nPos);

                if (item >= ld->Data)
                {
                    if (nRight == nLeft || nPos == nLeft)
                    {
                        this->InserNodeFront(ld, item);
                        return true;
                    }
                    nRight = nPos - 1;
                }
                else
                {
                    if (nRight == nLeft || nPos == nRight)
                    {
                        this->InserNodeBack(ld, item);
                        return true;
                    }
                    nLeft = nPos + 1;
                }

                nPos = nLeft + (nRight - nLeft + 1) / 2;
            }
        }
        else
        {
            _DListNode<T>* ld = null;

            while (nRight >= 0 && nLeft >= 0)
            {
                ld = this->IndexOfNode(nPos);

                if (item <= ld->Data)
                {
                    if (nRight == nLeft || nPos == nLeft)
                    {
                        this->InserNodeFront(ld, item);
                        return true;
                    }
                    nRight = nPos - 1;
                }
                else
                {
                    if (nRight == nLeft || nPos == nRight)
                    {
                        this->InserNodeBack(ld, item);
                        return true;
                    }
                    nLeft = nPos + 1;
                }
                nPos = nLeft + (nRight - nLeft + 1) / 2;
            }
        }
        return true;
    }
  

    /// <summary>
    /// 确定某元素是否在列表中
    /// </summary>
    /// <param name="item">查找的对象。对于引用类型,该值可以为 null。</param>
    /// <returns>如果在列表中找到 item,则为 true,否则为 false。</returns>
    bool Contains(const T& item) override
    {
        
        if (this->_Count == 0) return false;
        if (this->_Count == 1) return this->_First->Data == item;
        if (this->_Count == 2) return this->_First->Data == item || this->_First->Next->Data == item;

        int nPos = (int)this->_Count / 2;   //nPos在中间,所以无素一定要大于等于3才行
        int nLeft = 0;   //左边远素
        int nRight = (int)this->_Count - 1;  //右边远素

        _DListNode<T>* ld = null;

        if (this->_so == _SortOrder::s_Maxmin)
        {
            while (nRight >= 0 && nLeft >= 0)
            {
                ld = this->IndexOfNode(nPos);
                int iCom = item.CompareTo(ld->Data);
                if (iCom > 0)
                {
                    if (nRight == nLeft || nPos == nLeft)
                    {
                        return false;
                    }
                    nRight = nPos - 1;
                }
                else if (iCom < 0)
                {
                    if (nRight == nLeft || nPos == nRight)
                    {
                        return false;
                    }
                    nLeft = nPos + 1;
                }
                else
                {
                    return true;
                }
                nPos = nLeft + (nRight - nLeft + 1) / 2;
            }
        }
        else
        {
            while (nRight >= 0 && nLeft >= 0)
            {
                ld = this->IndexOfNode(nPos);
                int iCom = item.CompareTo(ld->Data);

                if (iCom < 0)
                {
                    if (nRight == nLeft || nPos == nLeft)
                    {
                        return false;
                    }
                    nRight = nPos - 1;
                }
                else if (iCom > 0)
                {
                    if (nRight == nLeft || nPos == nRight)
                    {
                        return false;
                    }
                    nLeft = nPos + 1;
                }
                else
                {
                    return true;
                }
                nPos = nLeft + (nRight - nLeft + 1) / 2;
            }
        }
        return false;
    }


};



//


                                //_SUStrList



// 
/// <summary>
/// 值都是唯一的字符串列表,且已排好序,区分大小写
/// </summary>
template<class T>
class _SUStrList : public  _SStrList<T>
{
public:
    bool Add(const T& item)override
    {
        if (this->Contains(item))
            return false;

        return _SStrList<T>::Add(item);
    }

    _SUStrList(_SortOrder so = _SortOrder::s_Minmax) : _SStrList<T>(so)
    {

    }

};

//


                                //_SUStrListUI



// 
/// <summary>
/// _SUStrListUI 值都是唯一,且已排序的字符串列表,不区分大小写
/// </summary>
template<class T>
class _SUStrListUI : public _SUStrList<T>
{
public:
    _SUStrListUI(_SortOrder  st) : _SUStrList<T>(st)
    {

    }


    /// <summary>
    /// 确定某元素是否在列表中
    /// </summary>
    /// <param name="item">查找的对象。对于引用类型,该值可以为 null。</param>
    /// <returns>如果在列表中找到 item,则为 true,否则为 false。</returns>
    bool Contains(const T& item) override
    {
        
        if (this->_Count == 0) return false;
        if (this->_Count == 1) return this->_First->Data.ToLower().CompareTo(item.ToLower()) == 0;
        if (this->_Count == 2) return this->_First->Data.ToLower().CompareTo(item.ToLower()) == 0 || this->_First->Next->Data.ToLower().CompareTo(item.ToLower()) == 0;

        int nPos = (int)this->_Count / 2;   //nPos在中间,所以无素一定要大于等于3才行
        int nLeft = 0;   //左边远素
        int nRight = (int)this->_Count - 1;  //右边远素

        _DListNode<T>* ld = null;

        if (this->_so == _SortOrder::s_Maxmin)
        {
            while (nRight >= 0 && nLeft >= 0)
            {
                ld = this->IndexOfNode(nPos);
                int iCom = item.ToLower().CompareTo(ld->Data.ToLower());
                if (iCom > 0)
                {
                    if (nRight == nLeft || nPos == nLeft)
                    {
                        return false;
                    }
                    nRight = nPos - 1;
                }
                else if (iCom < 0)
                {
                    if (nRight == nLeft || nPos == nRight)
                    {
                        return false;
                    }
                    nLeft = nPos + 1;
                }
                else
                {
                    return true;
                }
                nPos = nLeft + (nRight - nLeft + 1) / 2;
            }
        }
        else
        {
            while (nRight >= 0 && nLeft >= 0)
            {
                ld = this->IndexOfNode(nPos);
                int iCom = item.ToLower().CompareTo(ld->Data.ToLower());

                if (iCom < 0)
                {
                    if (nRight == nLeft || nPos == nLeft)
                    {
                        return false;
                    }
                    nRight = nPos - 1;
                }
                else if (iCom > 0)
                {
                    if (nRight == nLeft || nPos == nRight)
                    {
                        return false;
                    }
                    nLeft = nPos + 1;
                }
                else
                {
                    return true;
                }
                nPos = nLeft + (nRight - nLeft + 1) / 2;
            }
        }
        return false;
    }

     

};// _SUStrListUI











_LF_END_
#endif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/887261.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

QT--基础

将默认提供的程序都注释上意义 0101.pro QT core gui #QT表示要引入的类库 core&#xff1a;核心库 gui&#xff1a;图形化界面库 #如果要使用其他库类中的相关函数&#xff0c;则需要加对应的库类后&#xff0c;才能使用 greaterThan(QT_MAJOR_VERSION, 4): QT wid…

算法: 二分查找题目练习

文章目录 二分查找二分查找在排序数组中查找元素的第一个和最后一个位置搜索插入位置x 的平方根山脉数组的峰顶索引寻找峰值寻找旋转排序数组中的最小值点名 总结精华模版 二分查找 二分查找 没啥可说的,轻轻松松~ class Solution {public int search(int[] nums, int target…

栈的介绍与实现

一. 概念与结构 栈&#xff1a;⼀种特殊的线性表&#xff0c;其只允许在固定的⼀端进⾏插⼊和删除元素操作。进⾏数据插⼊和删除操作的⼀端称为栈顶&#xff0c;另⼀端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out的原则。 压栈&#xff1a;栈的插…

二叉树进阶学习——从前序和中序遍历序列构造二叉树

1.题目解析 题目来源&#xff1a;105.从前序与中序遍历序列构造二叉树——力扣 测试用例 2.算法原理 首先要了解一个概念 前序遍历&#xff1a;按照 根节点->左子树->右子树的顺序遍历二叉树 中序遍历&#xff1a;按照 左子树->根节点->右子树的顺序遍历二叉树 题目…

在 Kali Linux 中安装 Impacket

步骤 1&#xff1a;更新系统 打开终端并确保你的系统是最新的&#xff1a; sudo apt update && sudo apt upgrade -y 步骤 2&#xff1a;安装依赖 在安装 Impacket 之前&#xff0c;你需要确保安装了 Python 和一些必要的依赖。通常&#xff0c;Kali 已经预装了 Pytho…

影刀RPA实战:Excel拆分与合并工作表

1.影刀操作excel的优势 Excel&#xff0c;大家都不陌生&#xff0c;它是微软公司推出的一款电子表格软件&#xff0c;它是 Microsoft Office 套件的一部分。Excel 以其强大的数据处理、分析和可视化功能而闻名&#xff0c;广泛应用于商业、教育、科研等领域。可以说&#xff0…

YOLO11改进|注意力机制篇|引入ELA注意力机制

目录 一、【ELA】注意力机制1.1【ELA】注意力介绍1.2【ELA】核心代码 二、添加【ELA】注意力机制2.1STEP12.2STEP22.3STEP32.4STEP4 三、yaml文件与运行3.1yaml文件3.2运行成功截图 一、【ELA】注意力机制 1.1【ELA】注意力介绍 这篇论文的作者通过分析Coordinate Attention(C…

Java Supplier和Consumer接口

Supplier 在Java中&#xff0c;Supplier接口是一个重要的函数式接口&#xff0c;它属于java.util.function包&#xff0c;Supplier通常用于延迟计算或生成值的场景。Supplier接口是一个泛型接口&#xff0c;其get()方法不接受任何参数但返回一个泛型类型T的值。 这个接口被注解…

STM32新建工程-基于库函数

目录 一、创建一个新工程 二、为工程添加文件和路径 三、创建一个main.c文件&#xff0c;并调试 四、修改一些配置 五、用库函数进行写程序 1、首先加入一些库函数和头文件 2、编写库函数程序 一、创建一个新工程 我这里选择STM32F103C8的型号&#xff0c;然后点击OK。 …

Maven下载、安装与环境配置详解:从零开始搭建高效Java开发环境

下载 官方网站&#xff1a;http://maven.apache.org/ 下载页面&#xff1a;http://maven.apache.org/download.cgi 官网 下载页面 注&#xff1a;本教程使用的是3.3.9版本的maven。 安装 maven安装包下载完成后是一个压缩文件&#xff0c;如下图所示&#xff1a; 我们需要将…

java 数据存储方式

1. 变量存储 这是最基本的数据存储方式&#xff0c;通过声明变量来存储数据。变量可以是基本数据类型&#xff08;如int、float、char等&#xff09;&#xff0c;也可以是引用数据类型&#xff08;如对象、数组等&#xff09;。变量存储的数据通常存储在内存中&#xff0c;随着…

Redis --- 第三讲 --- 通用命令

一、get和set命令 Redis中最核心的两个命令 get 根据key来取value set 把key和value存储进去 redis是按照键值对的方式存储数据的。必须要先进入到redis客户端。 语法 set key value &#xff1a; key和value都是字符串。 对于上述这里的key value 不需要加上引号&#…

【D3.js in Action 3 精译_028】3.4 小节 DIY 实战:使用 Observable 在线绘制 D3 条形图

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一部分 D3.js 基础知识 第一章 D3.js 简介&#xff08;已完结&#xff09; 1.1 何为 D3.js&#xff1f;1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践&#xff08;上&#xff09;1.3 数据可…

关于Fake Location定位,运动世界校园问题

不好意思&#xff0c;之前那个文章其实是很早之前的&#xff0c;不知道为什么审核了很久一直没有通过&#xff0c;然后前几周莫名其妙点了一下重新发布&#xff0c;竟然发布成功了&#xff0c;这个方法已经失效了&#xff0c;要可以稳定&#xff0c;我建议是买一台root的手机&a…

Discord:报错:A fatal Javascript error occured(解决办法)

按 Windows 键 R 并输入 %appdata% 选择 discord 文件夹并将其删除。 再次按 Windows 键 R 并输入 %LocalAppData% 选择 discord 文件夹并再次将其删除。 附加&#xff1a; 如果还不行&#xff0c;就通过官网下载吧&#xff0c;这个问题通过epic下载可能会有

初识算法 · 滑动窗口(1)

目录 前言&#xff1a; 长度最小的子数组 题目解析 算法原理 算法编写 无重复长度的最小字符串 题目解析 算法原理 算法编写 前言&#xff1a; 本文开始&#xff0c;介绍的是滑动窗口算法类型的题目&#xff0c;滑动窗口本质上其实也是双指针&#xff0c;但是呢&#…

算法笔记(七)——哈希表

文章目录 两数之和判定是否互为字符重排存在重复元素存在重复元素 II字母异位词分组 哈希表&#xff1a;一种存储数据的容器&#xff1b; 可以快速查找某个元素&#xff0c;时间复杂度O(1)&#xff1b; 当频繁查找某一个数时&#xff0c;我们可以使用哈希表 创建一个容器&#…

YOLOv4和Darknet实现坑洼检测

关于深度实战社区 我们是一个深度学习领域的独立工作室。团队成员有&#xff1a;中科大硕士、纽约大学硕士、浙江大学硕士、华东理工博士等&#xff0c;曾在腾讯、百度、德勤等担任算法工程师/产品经理。全网20多万粉丝&#xff0c;拥有2篇国家级人工智能发明专利。 社区特色…

插画共享系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;插画信息管理&#xff0c;基础数据管理&#xff0c;论坛管理&#xff0c;公告信息管理&#xff0c;轮播图信息管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;插画信…

【JAVA开源】基于Vue和SpringBoot的服装生产管理系统

本文项目编号 T 066 &#xff0c;文末自助获取源码 \color{red}{T066&#xff0c;文末自助获取源码} T066&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…