自己写的一个CDeque可以给有志于在模板算法方面专研的人提供参考

本文介绍了一种自定义的双端队列实现方法,该队列使用模板类设计,并支持随机访问迭代器,适用于需要高效插入和删除操作的场景。文章详细解释了其内部结构及操作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include "Tool.h"
#include <malloc.h>

#pragma warning(disable:4996)

/*队列中控器节点结构*/
template<typename _Ty>
class CControl
{
public:
 size_t _start;/*子序列段的当前位置*/
 size_t _finish;/*子序列段的最后一个有元素的位置*/
 _Ty* _data;/*指向子序列的指针*/

 CControl()
 {
  _data  = NULL;
 }
};

/*常量迭代器类型*/
template<typename _Ty,size_t SIZE = SUBSIZE>
class CConstIterator;

 

/*普通迭代器类型(外部表现为随机迭代器)*/
template<typename _Ty,size_t SIZE = SUBSIZE>
class CIterator:public iterator<random_access_iterator_tag,_Ty>
{
 friend CConstIterator<_Ty,SIZE>;
public:
 CControl<_Ty>* _controlptr;/*指向一个子序列的指针*/
 size_t _cur;/*记录在子序列中的当前位置*/
public:
 CIterator()
 {
  _controlptr = NULL;
  _cur = 0;
 }

 CIterator(CControl<_Ty>* pControlRes):_controlptr(pControlRes),_cur(pControlRes->_start)
 {

 }
 CIterator(const CIterator<_Ty,SIZE>& citerRes):_controlptr(citerRes._controlptr),_cur(citerRes._cur)
 {

 }
 CIterator& operator = (const CIterator<_Ty,SIZE>& citerRes)
 {
  if(this != &citerRes)
  {
   _controlptr = citerRes._controlptr;
   _cur = citerRes._cur;
   return *this;
  }
 }

 bool operator == (const CIterator<_Ty,SIZE>& citerRes) const
 {

  if(_controlptr == citerRes._controlptr)
  {
   return _cur == citerRes._cur;
  }
  else
  {
   return false;
  }
 }

 bool operator != (const CIterator<_Ty,SIZE>& citerRes) const
 {
  if(_controlptr == citerRes._controlptr)
  {
   return _cur != citerRes._cur;
  }
  else
  {
   return true;
  }
 }

 bool operator > (const CIterator<_Ty,SIZE>& citerRes) const
 {

  if(_controlptr == citerRes._controlptr)
  {
   return _cur > citerRes._cur;
  }
  else
  {
   return _controlptr > citerRes._controlptr;
  }

 }

 bool operator <(const CIterator<_Ty,SIZE>& citerRes) const
 {

  if(_controlptr == citerRes._controlptr)
  {
   return _cur < citerRes._cur;
  }
  else
  {
   return _controlptr < citerRes._controlptr;
  }

 }

 bool operator >= (const CIterator<_Ty,SIZE>& citerRes) const
 {

  if(_controlptr == citerRes._controlptr)
  {
   return _cur >= citerRes._cur;
  }
  else
  {
   return _controlptr >= citerRes._controlptr;
  }

 }

 bool operator <= (const CIterator<_Ty,SIZE>& citerRes) const
 {

  if(_controlptr == citerRes._controlptr)
  {
   return _cur <= citerRes._cur;
  }
  else
  {
   return _controlptr <= citerRes._controlptr;
  }

 }

 size_t operator - (const CIterator<_Ty,SIZE>& citerRes) const
 {
  if(0 == (_controlptr - citerRes._controlptr))
  {
   return _cur - citerRes._cur;
  }
  else
  {
   return (_controlptr - citerRes._controlptr - 1) * SIZE + (_cur + SIZE - citerRes._cur);
  }
 }

 CIterator<_Ty,SIZE> operator - (size_t n) const
 {

  CIterator<_Ty,SIZE> citTmp = *this;
  if(citTmp._cur >= n)
  {
   citTmp._cur -= n;
  }
  else
  {
   size_t stTmp = n - citTmp._cur;
   citTmp._controlptr -= (((stTmp % SIZE) == 0)?(stTmp / SIZE):(stTmp / SIZE + 1));
   citTmp._cur = _controlptr->_finish - ((stTmp % SIZE == 0)?1:(stTmp % SIZE));
  }

  return citTmp;
 }

 CIterator<_Ty,SIZE>& operator -= (size_t n)
 {
  if(_cur >= n)
  {
   _cur -= n;
  }
  else
  {
   size_t stTmp = n - _cur;
   _controlptr -= (((stTmp % SIZE) == 0)?(stTmp / SIZE):(stTmp / SIZE + 1));
   _cur = _controlptr->_finish - ((stTmp % SIZE == 0)?1:(stTmp % SIZE));
  }

  return *this;
 }

 CIterator<_Ty,SIZE> operator + (size_t n) const
 {

  CIterator<_Ty,SIZE> citTmp = *this;
  if(citTmp._cur + n < citTmp._controlptr->_finish)
  {
   citTmp._cur += n;
  }
  else
  {
   size_t stTmp = n - (citTmp._controlptr->_finish - citTmp._cur);
   citTmp._controlptr += (stTmp / SIZE + 1);
   citTmp._cur = stTmp % SIZE;
  }

  return citTmp;
 }

 CIterator<_Ty,SIZE>& operator += (size_t n)
 {
  if(_cur + n < _controlptr->_finish)
  {
   _cur += n;
  }
  else
  {
   size_t stTmp = n - (_controlptr->_finish - _cur);
   cout << "stTmp == " << stTmp << " n == " << n << endl;
   _controlptr += stTmp / SIZE + 1;
   _cur = stTmp % SIZE;
  }

  return *this;
 }

 CIterator<_Ty,SIZE>& operator ++ ()
 {
  if(_cur < _controlptr->_finish -1)
  {
   _cur++;
  }
  else if(_controlptr->_finish == SIZE)
  {
   _controlptr += 1;
   _cur = 0;
  }
  else
  {
   _cur++;
  }

  return *this;
 }

 CIterator<_Ty,SIZE> operator ++ (int)
 {
  CIterator<_Ty,SIZE> citTmp = *this;
  ++(*this);
  return citTmp;
 }

 CIterator<_Ty,SIZE>& operator -- ()
 {
  return *this -= 1;
 }

 CIterator<_Ty,SIZE> operator -- (int)
 {
  CIterator<_Ty,SIZE> citTmp = *this;
  *this -= 1;

  return citTmp;
 }

 _Ty& operator * ()
 {

  return *(_controlptr->_data + _cur);
 }

 _Ty* operator -> ()
 {
  return (_controlptr->_data + _cur);
 }
};

/*常量迭代器类型(外部表现为随机迭代器)*/
template<typename _Ty,size_t SIZE>
class CConstIterator:public iterator<random_access_iterator_tag,_Ty>
{
public:
 CControl<_Ty>* _controlptr;/*指向一个子序列的指针*/
 size_t _cur;/*记录在子序列中的当前位置*/
public:
 CConstIterator()
 {
  _controlptr = NULL;
  _cur = 0;
 }

 CConstIterator(CControl<_Ty>* pControlRes):_controlptr(pControlRes),_cur(pControlRes->_start)
 {

 }
 CConstIterator(const CIterator<_Ty,SIZE>& citerRes):_controlptr(citerRes._controlptr),_cur(citerRes._cur)
 {

 }
 CConstIterator(const CConstIterator<_Ty,SIZE>& citerRes):_controlptr(citerRes._controlptr),_cur(citerRes._cur)
 {

 }
 CConstIterator<_Ty,SIZE>& operator = (const CConstIterator<_Ty,SIZE>& citerRes)
 {
  if(this != &citerRes)
  {
   _controlptr = citerRes._controlptr;
   _cur = citerRes._cur;
   return *this;
  }
 }

 bool operator == (const CConstIterator<_Ty,SIZE>& citerRes) const
 {

  if(_controlptr == citerRes._controlptr)
  {
   return _cur == citerRes._cur;
  }
  else
  {
   return false;
  }
 }

 bool operator != (const CConstIterator<_Ty,SIZE>& citerRes) const
 {
  if(_controlptr == citerRes._controlptr)
  {
   return _cur != citerRes._cur;
  }
  else
  {
   return true;
  }
 }

 bool operator > (const CConstIterator<_Ty,SIZE>& citerRes) const
 {

  if(_controlptr == citerRes._controlptr)
  {
   return _cur > citerRes._cur;
  }
  else
  {
   return _controlptr > citerRes._controlptr;
  }

 }

 bool operator <(const CConstIterator<_Ty,SIZE>& citerRes) const
 {

  if(_controlptr == citerRes._controlptr)
  {
   return _cur < citerRes._cur;
  }
  else
  {
   return _controlptr < citerRes.pControlRes;
  }

 }

 bool operator >= (const CConstIterator<_Ty,SIZE>& citerRes) const
 {

  if(_controlptr == citerRes._controlptr)
  {
   return _cur >= citerRes._cur;
  }
  else
  {
   return _controlptr >= citerRes._controlptr;
  }

 }

 bool operator <= (const CConstIterator<_Ty,SIZE>& citerRes) const
 {

  if(_controlptr == citerRes._controlptr)
  {
   return _cur <= citerRes._cur;
  }
  else
  {
   return _controlptr <= citerRes._controlptr;
  }

 }

 size_t operator - (const CConstIterator<_Ty,SIZE>& citerRes) const
 {

  if(0 == (_controlptr - citerRes._controlptr))
  {
   return _cur - citerRes._cur;
  }
  else
  {
   return (_controlptr - citerRes._controlptr - 1) * SIZE + (_cur + SIZE - citerRes._cur);
  }
 }

 CConstIterator<_Ty,SIZE> operator - (size_t n) const
 {

  CConstIterator<_Ty,SIZE> citTmp = *this;
  if(citTmp._cur >= n)
  {
   citTmp._cur -= n;
  }
  else
  {
   size_t stTmp = n - citTmp._cur;
   citTmp._controlptr -= (((stTmp % SIZE) == 0)?(stTmp / SIZE):(stTmp / SIZE + 1));
   citTmp._cur = _controlptr->_finish - ((stTmp % SIZE == 0)?1:(stTmp % SIZE));
  }

  return citTmp;
 }

 CConstIterator<_Ty,SIZE>& operator -= (size_t n)
 {
  if(_cur >= n)
  {
   _cur -= n;
  }
  else
  {
   size_t stTmp = n - _cur;
   _controlptr -= (((stTmp % SIZE) == 0)?(stTmp / SIZE):(stTmp / SIZE + 1));
   _cur = _controlptr->_finish - ((stTmp % SIZE == 0)?1:(stTmp % SIZE));
  }

  return *this;
 }

 CConstIterator<_Ty,SIZE> operator + (size_t n)
 {

  CConstIterator<_Ty,SIZE> citTmp = *this;
  if(citTmp._cur + n < citTmp._controlptr->_finish)
  {
   citTmp._cur += n;
  }
  else
  {
   size_t stTmp = n - (citTmp._controlptr->_finish - citTmp._cur);
   citTmp._controlptr += (stTmp / SIZE + 1);
   citTmp._cur = stTmp % SIZE;
  }

  return citTmp;
 }

 CConstIterator<_Ty,SIZE>& operator += (size_t n) const
 {

  if(_cur + n < _controlptr->_finish)
  {
   _cur += n;
  }
  else
  {
   size_t stTmp = n - (_controlptr->_finish - _cur);
   _controlptr += (stTmp / SIZE + 1);
   _cur = stTmp % SIZE;
  }

  return *this;
 }

 CConstIterator<_Ty,SIZE>& operator ++ ()
 {
  if(_cur < _controlptr->_finish -1)
  {
   _cur++;
  }
  else if(_controlptr->_finish == SIZE)
  {
   _controlptr += 1;
   _cur = 0;
  }
  else
  {
   _cur++;
  }

  return *this;
 }

 CConstIterator<_Ty,SIZE> operator ++ (int)
 {
  CConstIterator<_Ty> citTmp = *this;
  ++(*this);
  return citTmp;
 }

 CConstIterator<_Ty,SIZE>& operator -- ()
 {
  return *this -= 1;
 }

 CConstIterator<_Ty,SIZE> operator -- (int)
 {
  CConstIterator<_Ty,SIZE> citTmp = *this;
  *this -= 1;

  return citTmp;
 }

 const _Ty& operator * ()
 {
  return *(_controlptr->_data + _cur);
 }

 const _Ty* operator -> () const
 {
  return (_controlptr->_data + _cur);
 }
};


/*队列结构*/
template<typename _Ty,size_t SIZE = SUBSIZE>
class CDeque
{
private:
 CControl<_Ty>* _maparray;/*Deque内部 核心数据成员*/
 size_t _size;/*队列的大小*/
 size_t _capacity;/*队列的容量*/
 size_t _begin;/*记录有效数据在中控器的开始位置*/
 size_t _end;/*记录有效数据在中控器的结束位置*/

public:
 typedef CIterator<_Ty,SIZE> iterator;/*deque 普通迭代器*/
 typedef CConstIterator<_Ty,SIZE> const_iterator;/*常量迭代器*/
public:
 /*默认无参数构造函数*/
 CDeque()
 {
  _maparray = NULL;
  _size = 0;
  _capacity = 0;
  _begin = 0;
  _end = 0;
 }

 CDeque(size_t stSize,const _Ty& ty = _Ty())
 {
  G_Assert(stSize < size_t(-1),g_ErrorMsg[NUMBERRANGEERROR])
   size_t stLen = 2 * ((stSize) / SIZE) + 5;/*默认情况下扩充2倍加5个子序列长度*/
  size_t stBegin = stLen  / 4;/*中控器中的开始位置*/

  _begin = stBegin;
  _size = stSize;
  _capacity = stLen * SIZE;

  _maparray = new CControl<_Ty>[stLen];
  G_Assert(NULL != _maparray,g_ErrorMsg[MEMORYFAIL])

   for(size_t i = 0;i < stLen;i++)
   {
    _maparray[i]._data = new _Ty[SIZE];

    G_Assert(NULL != _maparray[i]._data,g_ErrorMsg[MEMORYFAIL])

    _maparray[i]._start = 0;
    _maparray[i]._finish = 0;
   }

   if(_Ty() != ty)
   {
    /*从中控器中的开始位填充内存*/
    size_t stK = (stSize) / SIZE;
    for(size_t i = stBegin;i < stBegin + (stSize) / SIZE;i++)
    {
     for(size_t j = 0;j < SIZE;j++)
     {
      _maparray[i]._data[j] = ty;
     }

     _maparray[i]._finish = SIZE;
    }

    size_t stLen2 = (stSize) % SIZE;

    for(size_t i = 0;i < stLen2;i++)
    {
     _maparray[stBegin + (stSize) / SIZE]._data[i] = ty;
    }

    if(stLen2 > 0)
    {
     _maparray[stBegin + (stK)]._finish = stLen2;
     _end = stBegin + stK;
    }
    else
    {
     _end = stBegin + stK;
    }
   }
 }

 CDeque(iterator first,iterator last)
 {

  G_Assert(last > first,g_ErrorMsg[ITERATORRANGEERROR])

   size_t stLen = 2 * (last - first) / SIZE + 5;/*默认情况下扩充2倍加5个子序列长度*/
  size_t stBegin = stLen  / 4;/*中控器中的开始位置*/

  _begin = stBegin;
  _size = (last - first);
  _capacity = stLen * SIZE;

  _maparray = new CControl<_Ty>[stLen];
  G_Assert(NULL != _maparray,g_ErrorMsg[MEMORYFAIL])

   for(size_t i = 0;i < stLen;i++)
   {
    _maparray[i]._data = new _Ty[SIZE];
    G_Assert(NULL != _maparray[i]._data,g_ErrorMsg[MEMORYFAIL])

     _maparray[i]._start = 0;
    _maparray[i]._finish = 0;
   }

   /*从中控器中的开始位填充内存*/
   size_t stK = (last - first) / SIZE;
   for(size_t i = stBegin;i < stBegin + stK;i++)
   {
    for(size_t j = 0;j < SIZE;j++)
    {
     _maparray[i]._data[j] = *first++;
    }

    _maparray[i]._finish = SIZE;
   }
   size_t stLen2 = (last - first) % SIZE;

   for(size_t i = 0;i < stLen2;i++)
   {
    _maparray[stBegin + stK]._data[i] = *first++;
   }

   if(stLen2 > 0)
   {
    _maparray[stBegin + (stK)]._finish = stLen2;
    _end = stBegin + stK;
   }
   else
   {
    _end = stBegin + stK;
   }

 }

 template<typename randomaccessiterator>
 CDeque(randomaccessiterator first,randomaccessiterator last)
 {
  G_Assert(last > first,g_ErrorMsg[ITERATORRANGEERROR])

   size_t stLen = 2 * (last - first) / SIZE + 5;/*默认情况下扩充2倍加5个子序列长度*/
  size_t stBegin = stLen  / 4;/*中控器中的开始位置*/

  _begin = stBegin;
  _size = (last - first);
  _capacity = stLen * SIZE;

  _maparray = new CControl<_Ty>[stLen];
  G_Assert(NULL != _maparray,g_ErrorMsg[MEMORYFAIL])

   for(size_t i = 0;i < stLen;i++)
   {
    _maparray[i]._data = new _Ty[SIZE];
    G_Assert(NULL != _maparray[i]._data,g_ErrorMsg[MEMORYFAIL])

    _maparray[i]._start = 0;
    _maparray[i]._finish = 0;
   }

   /*从中控器中的开始位填充内存*/
   size_t stK = (last - first) / SIZE;
   for(size_t i = stBegin;i < stBegin + stK;i++)
   {
    for(size_t j = 0;j < SIZE;j++)
    {
     _maparray[i]._data[j] = *first++;
    }

    _maparray[i]._finish = SIZE;
   }
   size_t stLen2 = (last - first) % SIZE;

   for(size_t i = 0;i < stLen2;i++)
   {
    _maparray[stBegin + stK]._data[i] = *first++;
   }

   if(stLen2 > 0)
   {
    _maparray[stBegin + (stK)]._finish = stLen2;
    _end = stBegin + stK;
   }
   else
   {
    _end = stBegin + stK;
   }
 }

 CDeque(const CDeque<_Ty,SIZE>& queueRes)
 {

  CDeque<_Ty,SIZE>* cdTmp = new CDeque<_Ty,SIZE>(queueRes.begin(),queueRes.end());
  G_Assert(NULL != cdTmp,g_ErrorMsg[MEMORYFAIL])
   memcpy(this,cdTmp,sizeof(*cdTmp));
 }

 CDeque<_Ty,SIZE>& operator = (const CDeque<_Ty,SIZE>& queueRes)
 {

  if(this != &queueRes)
  {
   /*对以前空间的回收*/
   if(!empty())
   {
    for(size_t i = 0;i < _capacity / SIZE;i++)
    {
     delete [] _maparray[i]._data;
    }

    delete [] _maparray;
    _maparray = NULL;
   }

   CDeque<_Ty,SIZE>* cdTmp = new CDeque<_Ty,SIZE>(queueRes.begin(),queueRes.end());
   G_Assert(NULL != cdTmp,g_ErrorMsg[MEMORYFAIL]);
   memcpy(this,cdTmp,sizeof(*cdTmp));

   return *this;
  }
 }

 iterator begin()
 {
  return CIterator<_Ty,SIZE>(_maparray + _begin);
 }

 iterator end()
 {
  CIterator<_Ty,SIZE> citTmp;
  citTmp._controlptr = _maparray + _end;
  citTmp._cur = (_maparray + _end)->_finish;
  return citTmp;
 }

 const_iterator begin() const
 {
  return CIterator<_Ty,SIZE>(_maparray + _begin);
 }

 const_iterator end() const
 {
  CIterator<_Ty,SIZE> citTmp;
  citTmp._controlptr = _maparray + _end;
  citTmp._cur = (_maparray + _end)->_finish;
  return citTmp;
 }

 bool empty() const
 {
  return _maparray == NULL;
 }

 _Ty& operator [] (size_t stRes) const
 {
  return *(begin() + stRes);
 }

 void resize(size_t stRes)
 {
  cout << _end << endl;
  G_Assert(stRes < size_t(-1),g_ErrorMsg[NUMBERRANGEERROR])
   if(stRes >= _capacity)
   {
    _capacity = (stRes) + 5 * SIZE;
    size_t mapsize = _capacity / SIZE +1;
    cout << "mapsize == " << mapsize << endl;
    _capacity = mapsize * SIZE;

    CControl<_Ty>* _maparrayTmp = new CControl<_Ty>[mapsize];
    G_Assert(NULL != _maparrayTmp,g_ErrorMsg[MEMORYFAIL])

     cout << "_end == " << _end << endl;
        for(size_t i = 0;i < _begin;i++)
     {
      _maparrayTmp[i]._data = new _Ty[SIZE];
      G_Assert(NULL != _maparrayTmp[i]._data,g_ErrorMsg[MEMORYFAIL])

      _maparrayTmp[i]._start = 0;
      _maparrayTmp[i]._finish = 0;
     }
     for(size_t i = _end + 1;i < mapsize;i++)
     {
      _maparrayTmp[i]._data = new _Ty[SIZE];
      G_Assert(NULL != _maparrayTmp[i]._data,g_ErrorMsg[MEMORYFAIL])

         _maparrayTmp[i]._start = 0;
      _maparrayTmp[i]._finish = 0;
     }

     for(size_t i = _begin;i <= _end;i++)
     {
      _maparrayTmp[i]._data = _maparray[i]._data;
      _maparrayTmp[i]._start = _maparray[i]._start;
      _maparrayTmp[i]._finish = _maparray[i]._finish;
     }

     cout << _begin << "_end ===>>> " << _end << _maparrayTmp[_end - 1]._finish << endl;

     delete [] _maparray;
     _maparray = _maparrayTmp;
   }
   else/*否则直接返回*/
   {
    return;
   }
 }

 void push_back(const _Ty& ty)
 {
  if(_size + 1 >= _capacity)
  {
   resize(_size + 1);
  }

  if(_maparray[_end]._finish >= SIZE)
  {
   _end++;
   (_maparray[_end]._data[_maparray[_end]._finish++]) = ty;
  }
  else
  {
   _maparray[_end]._data[_maparray[_end]._finish++] = ty;
  }
  _size++;
 }

 void push_front(const _Ty& ty)
 {
  if(_size + 1 >= _capacity)
  {
   resize(_size + 1);
  }

  if(_maparray[_begin]._start <= 0)
  {
   _begin--;
   _maparray[_begin]._start = SIZE - 1;
   _maparray[_begin]._finish = SIZE;

   _maparray[_begin]._data[_maparray[_begin]._start] = ty;
  }
  else
  {
   _maparray[_begin]._data[--_maparray[_begin]._start] = ty;
  }

  _size++;
 }

 void pop_back()
 {
  G_Assert(!empty(),g_ErrorMsg[EMPTYDEQUE])
   if(_maparray[_end]._finish == 1)
   {
    _maparray[_end]._finish = 0;
    _end--;

   }
   else
   {
    _maparray[_end]._finish--;
   }

   _size--;
 }

 void pop_front()
 {
  G_Assert(!empty(),g_ErrorMsg[EMPTYDEQUE])
   if(_maparray[_begin]._start + 1 >= SIZE)
   {
    _maparray[_begin]._start = _maparray[_begin]._finish;
    _begin++;
   }
   else
   {
    _maparray[_begin]._start++;
   }

   _size--;
 }

 void frontorderprint() const
 {
  iterator iterTmp = begin();
  for(;iterTmp != end();++iterTmp)
  {
   cout << *iterTmp ;
  }
  cout << endl;
 }

 void backorderprint() const
 {
  iterator iterTmp = end();
  while(iterTmp != begin())
  {
   cout << *(--iterTmp);
  }
  cout << endl;
 }

 size_t size() const
 {
  return _size;
 }

 size_t capacity()
 {
  return _capacity;
 }

 template<typename randomaccessiterator>
 void assign(randomaccessiterator first,randomaccessiterator last)
 {
  G_Assert(last - first > 0,g_ErrorMsg[ITERATORRANGEERROR])

   /*如果以前存在空间删除以前的空间*/
   if(_capacity > 0)
   {
    for(size_t i = 0;i < _capacity / SIZE;i++ )
    {
     delete [] _maparray[i]._data;
    }
    delete [] _maparray;
   }

   CDeque<_Ty,SIZE>* cdTmp = new CDeque<_Ty,SIZE>(first,last);
   G_Assert(NULL != cdTmp,g_ErrorMsg[MEMORYFAIL]);
   memcpy(this,cdTmp,sizeof(*cdTmp));
 }

 /*鉴于在其他位置插入元素效率很低所以这里不提供插入相关接口*/

};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值