您好,登錄后才能下訂單哦!
C++通用棧代碼怎么編寫,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
先貼出代碼:
#include"stdafx.h" template <class T> class STACK { public: void operator--(int) { index--; } void operator-(long count) { index-=count; } void operator+(T value) { Push(value); } long operator+=(T value) { return PushDifferent(value); } T&operator[](long addr) { if(addr<0)return data[index+1+addr]; return data[addr]; } public: STACK() { basicLen=BASICLEN; len=0; data=NULL; index=-1; } STACK(long basiclen) { basicLen=basiclen; len=0; data=NULL; index=-1; } STACK(T initValue,long count) { this->basicLen=BASICLEN; this->len=0; index=-1; data=NULL; for(long i=0;i<count;i++)Push(initValue); } ~STACK() { } void Push(T value) { index++; Extern(); data[index]=value; } long PushDifferent(T value) { for(long i=0;i<=index;i++)if(data[i]==value)return i;//如果T是類,需要重載==。T不能是結構體。 Push(value); return -1; } void Pop() { index--; } void Pop(long count) { index-=count; } T Peek() { return data[index]; } T Peek(long index) { return data[index]; } void Set(T value) { data[index]=value; } void Set(long index,T value) { data[index]=value; } void Reset() { index=-1; } long Index() { return index; } long Id(T value) { for(long i=0;i<=index;i++)if(value==data[i])return i; return -1; } void SortMinToMax() { SortLong(data,index+1); } private: void SortLong(T*set,long count) { long i=0,j=count-1; long val=set[0]; if(count<2)return; while (i<j) { for(;j>i;j--)if(set[j]<val){set[i]=set[j];break;} for(;i<j;i++)if(set[i]>val){set[j]=set[i];break;} } set[i]=val; SortLong(set,i); SortLong(set+i+1,count-i-1); } void Extern() { if(index<len)return; T*tmp=new T[len+=basicLen]; for(long i=0;i<index;i++) tmp[i]=data[i]; if(data)delete[]data; data=tmp; } private: T*data; private: long index,len,basicLen; static const long BASICLEN=5; };
這是我最近做編譯器時自己創建的一個功能比較多的C++棧代碼,使用了模板類來作為棧的數據類型,所以理論上支持很多的數據類型,比如long,int,bool,char,char*.也支持用戶自定義的類(但請不要使用結構類型,否則可能會出錯)類型。
同時,為了便于棧的操作,在里面重載了一些運算符。我把這個棧的功能寫在下面便于大家參考:
0.初始化:(1)STACK():正常的初始化;默認的基本塊長度為5.
(2)STACK(long b):初始化時把棧的基本塊長度設為b.b應為正整數。這個初始化函數與第一個作用一樣,提供這個函數是為了讓用戶在程序執行速度與內存開銷間作一個合理的選擇。
(3)STACK(T iv,long c):初始化后在棧中寫入c個值為iv的數據。
1.入棧:(1)Push(T v)或+v:把數據v寫入棧頂。無返回值;
(2)PushDifferent(T v)或+=v:如果在棧里面沒有v這個數據,則把v寫入棧頂,返回值為-1;否則返回v在棧中的索引。(如果數據類型不是可比較大小的,則需要在那個數據類中重載==運算符(返回類型應為bool型),否則會出錯)
2.出棧:(1)Pop()或--:去掉處于棧頂的數據;
(2)Pop(long c)或-c:去掉自棧頂向下的c個數據;
3.讀棧:(1)Peek():讀出棧頂數據;
(2)Peek(long i):讀出棧中索引為i的數據;
(3)[i]:若i為非負數,返回棧中data[i]的引用,若i為負數,返回data[index+i+1]的引用。
4.置棧:(1)Set(T v)更改棧頂的數據為v;
(2)Set(long i,T v)更改棧中索引為i處的數據為v;
5.讀當前索引:Index():返回當前的索引值.棧底的索引為0,以此往上推。
6.重置棧:Reset():重置棧索引為-1,也就是清空棧(實際數據還在,只是棧索引沒有指向其中的數據了)。
7.讀取數據索引:Id(T v):如果棧中有數據v,返回v的索引;否則返回-1(表示沒有v)。
8.從小到大排序:SortMinToMax():把棧中的數據按從小到大的順序排列,這會改變棧中的數據。如果數據類型不是可比較大小的,則需要在那個數據類中重載<,>(返回類型應為bool型)這兩個運算符,否則會出錯。
9.私有函數說明:Extern():這個函數是當索引指針超過data的數據個數len時增大data的數據個數。在Push(T v)、PushDifferent(T v)和STACK(T iv,long c)中都會調用該函數以自動增大data的大小。
應用例子:
0.初始化:(1)STACK stack;//聲明了一個棧,名字為stack。
(2)STACK stack=STACK(2);//聲明了一個棧stack,這個棧的基本數據個數為2。
(3)STACK stack=STACK("fvck",8);//聲明了一個棧stack,并入其中寫入了8個"fvck"。
1.入棧:
STACK st;
(1)st.Push('a');//把a置入棧中
(2)st+'a';//同上
(3)st.PushDifferent('a');//若棧中沒有'a',把'a'置入棧中
(4)st+='a';//同上
2.出棧:假設棧st中有數據2,3,1,4,7
(1)st.Pop();//數據變為2,3,1,4
(2)st--;//同上
(3)st.Pop(2);//數據變為2,3,1
(4)st-2;//同上
3.讀棧:假設棧st中有數據2,5,3,4
(1)a=st.Peek();//a的值為4
(2)a=st.Peek(1);//a的值為5
(3)a.st.Peek(0);//工的值為2
(3)a=st[1];//a的值為5
(4)a=st[-1];//a的值為4
(5)a=st[-3];//工的值為5
置棧:
(6)st[0]=8;//棧中數據變為8,5,3,4
(7)st[-2]=9;//棧中數據變為2,5,9,4
從(3)~(7)我們看出可以把棧當成數組來使用,而且這個數組不需要聲明大小,但需要使用Push等函數來擴展長度。數組的索引可以為負,當為負時,-1表示棧頂,依次往下數。
4.置棧:假設棧st中有數據4,2,34,5,99
(1)st.Set(8);//棧中數據變為4,2,34,5,8
(2)st.Set(2,8);//棧中數據變為4,2,8,5,99
5.讀當前索引:假設棧st中有數據3,4,24,5,9,9,8
long i=st.Index();//i的值為6
6.重置棧:假設棧st中有數據23,4,2
st.Reset();//棧中沒有數據了
7.讀取數據索引:假設棧st中有數據2,33,4,22,5
(1)long i=st.Id(22);//i的值為3
(2)long i=st.Id(8);//i的值為-1
8.從小到大排序:假設棧st中有數據2,3,44,9,7
st.SortMinToMax();//棧中數據變為2,3,7,9,44
從2~8,為了方便,我們棧中的數據都是整數值,這是明顯可以比較大小的數據,那么對于用戶自定義的數據,怎么樣才能使用PushDifferent與+=呢?例子如下(這是我編譯器中的一個類聲明代碼):
class RANGE { public: static const unsigned long R_MIN=0,R_MAX=0xffff; //全部相等 bool operator==(RANGE v) { if(this->left==v.left&&this->right==v.right&&this->flag==v.flag)return true; return false; } bool operator<=(RANGE v) { if(v.flag==RANGE::WITHIN) { if(this->left>=v.left&&this->right<=v.right)return true; } else if(v.flag==RANGE::WITHOUT) { if(this->left>=R_MIN&&this->right<=v.left)return true; if(this->left>=v.right&&this->right<=R_MAX)return true; } return false; } public: RANGE() { } RANGE(long left,long right,int flag) { this->left=left; this->right=right; this->flag=flag; } public: enum{WITHIN,WITHOUT}; long left,right; int flag; };
在這個類中,重載了==運算符,而且返回值為bool型,所以RANGE類型的數據可以在PushDifferent與+=中使用。
看完上述內容,你們掌握C++通用棧代碼怎么編寫的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。