資料結構_字串
阿新 • • 發佈:2018-12-20
字串 堆的動態分配 My blog
//堆 動態分配 //realloc函式用於修改一個原先已經分配的記憶體塊的大小,可以使一塊記憶體的擴大或縮小。 //void *realloc (void *ptr, size_t new_size ); #include <iostream> #include <cstring> #include <algorithm> #include <cstdio> #include <stdlib.h> #define ll long long #define Status int #define OK 1 #define False 0 using namespace std; typedef struct { char *ch;// 指標。分配空間 int length;//字串的長度 }String; //初始化 void Str_init(String &S) { S.ch=NULL; S.length=0; } //生成一個其值等於chars的T串 Status Str_assign(String &S,char *chars) { int len=0; char *c; if(S.ch) free(S.ch);//釋放S串原有的空間 for(c=chars; *c ; c++)//注意是 *c { len++; } if(!len){//如果chars為空串 S.ch=NULL; S.length=0; }else{ if(!(S.ch=(char *)malloc(len*sizeof(char)))) return False; // cout<<len<<endl; for(int i=0;i<len;i++) { S.ch[i]=chars[i]; } S.length=len; } return OK; } //複製串 由S串複製得T串 Status Str_copy(String &T,String S) { if(!T.ch) free(T.ch); if(!(T.ch=(char *)malloc(sizeof(char)*S.length))) return False; if(!S.length) { S.ch=NULL; S.length=0; }else { for(int i=0;i<S.length;i++) { T.ch[i]=S.ch[i]; } T.length=S.length; } return OK; } //判斷是否為空串 Status Str_empty(String S) { if(S.length==0) return OK;//是空串 else return False;//不是空串 } //求串的長度 Status Str_length(String S) { return S.length;//返回S的長度 } //比較兩個串的大小 Status Str_compare(String S,String T) { for(int i=0;i<S.length&&i<T.length;i++) { if(S.ch[i]!=T.ch[i]) return S.ch[i]-T.ch[i]; //S>T 返回>0 S=T 返回=0 else 返回<0 } return S.length-T.length;//如果for迴圈裡都相同 看長度。 } //清空串 Status Str_clear(String &S) { if(S.ch){ free(S.ch); //清空指標指向的記憶體 S.ch=NULL; } S.length=0; return OK; } ////銷燬串 //Status Str_destory(String &S) //{ // free(S.ch); // S.ch=NULL; // S.length=0; // return OK; //}//串的堆分配為什麼 沒有 銷燬 //聯結兩個串 為T Status Str_concat(String &T,String S1,String S2) { if(T.ch) free(T.ch);//釋放舊空間 if(!(T.ch=(char *)malloc((S1.length+S2.length)*sizeof(char)))) return False; for(int i=0;i<S1.length;i++) { T.ch[i]=S1.ch[i]; } for(int i=0;i<S2.length;i++) { T.ch[S1.length+i]=S2.ch[i]; } T.length=S1.length+S2.length; return OK; } //返回串S中第pos個位置長度為len的子串 Status Str_sub(String *Sub,String S,int pos,int len) { if(pos<1||pos>S.length||len<0||len>S.length-pos+1) return False; if(Sub->ch) free(Sub->ch); if(!len) { Sub->ch=NULL; Sub->length=0; }else { Sub->ch=(char *)malloc(len*sizeof(char)); for(int i=0;i<len;i++) { Sub->ch[i]=S.ch[pos-1+i];//注意 } Sub->length=len; } return OK; } //返回串T在串S中第pos個 字元之後第一次出現的位置 (BF) Status Str_index(String S,String T,int pos) { if(pos<1||pos>S.length) return False; int i=pos-1,j=0; while(i<S.length&&j<T.length) { if(S.ch[i]==T.ch[j]) { i++; j++; }else { i=i-j+1; j=0; } } if(j>=T.length) return i-j+1; else return 0; } //求 next 陣列 /*有bug void Str_next(String T,int next[]) { int i=1,j=0; next[1]=0;//從1開始 while(i<T.length) { if(j==0||T.ch[i]==T.ch[j]) { ++i; ++j; next[i]=j; }else j=next[j]; //回溯 } } //返回串T在串S中第pos個 字元之後第一次出現的位置 (KMP) Status Str_index(String S,String T,int pos) { if(pos<1||pos>S.length||T.length>S.length-pos+1) return False; int i=pos,j=0; while(i<=S.length&&j<=T.length) { if(j==0||S.ch[i]==T.ch[j]) { i++; j++; }else j=next[j];//i一定都是 ++的 j一直在改變位置 (回溯) } if(j>T.length) return i-T.length; //匹配成功 else return False; } */ //在串S的第pos個位置之前插入串T Status Str_insert(String &S,int pos,String T) { if(pos<1||pos>S.length+1) return False; if(T.length) { S.ch=(char *)realloc(S.ch,(S.length+T.length)*sizeof(char));//申請空間 if(!S.ch) return False; for(int i=S.length-1;i>=pos-1;i--) { S.ch[i+T.length]=S.ch[i];//移位 } for(int i=0;i<T.length;i++) { S.ch[pos-1+i]=T.ch[i]; } S.length+=T.length; } return OK; } //在串S的第pos個位置刪除長度為len的子串 Status Str_delete(String &S,int pos,int len) { if(pos<1||pos>S.length||len<0||len>S.length-pos+1) return False; for(int i=pos-1+len;S.ch[i]!='\0';i++) { S.ch[i-len]=S.ch[i]; } S.length=S.length-len; return OK; } //用串V替換 S中子串為T的串 Status Str_replace(String &S,String T,String V) { int pos1=1; if(Str_empty(T)) return False; do { pos1=Str_index(S,T,pos1); //cout<<pos1<<endl; if(pos1) { Str_delete(S,pos1,T.length);//找到位置刪除 //Str_traverse(S); Str_insert(S,pos1,V);//插入 //Str_traverse(S); } }while(pos1); return OK; } //遍歷 void Str_traverse(String S) { for(int i=0;i<S.length;i++) { cout<<S.ch[i]; } cout<<endl; } int main() { int pos,len; char c[500],c1[100],c2[100]; String S,T,V,Sub,S1,S2; //初始化 Str_init(S); //輸入字串 安排 cout<<"Successful initialization"<<endl; cout<<"input assign string:"<<endl;//分配字元 gets(c);//gets 回車結束 Str_assign(S,c); //檢測assign是否正確 cout<<"S :"; Str_traverse(S); cout<<"The length of S: "; cout<<S.length<<endl; //刪除子串 cout<<"input position and length of the string you want to delete in S: "<<endl; cin>>pos>>len; if(Str_delete(S,pos,len)) { cout<<"After deleting: "; Str_traverse(S); }else cout<<"Error"<<endl; //插入子串 cout<<"input string and position you want to insert in S "<<endl; cout<<"(Blank space to separate) :"<<endl;//空格分開 先輸入string 在輸入pos cin>>c; cin>>pos; Str_assign(T,c);//為串T安排 // Str_traverse(T);//檢測 if(Str_insert(S,pos,T)) { cout<<"After inserting: "; Str_traverse(S); }else cout<<"Error"<<endl; //查詢子串 cout<<"input position and length you want to search in S :"<<endl; cin>>pos>>len; Str_init(Sub); if(Str_sub(&Sub,S,pos,len)) { cout<<"The Substring: "; Str_traverse(Sub); }else cout<<"Error"<<endl; //拼接 cout<<"input two new strings you need to concat:"<<endl; Str_init(T);//初始化 Str_init(S1); Str_init(S2);//記得初始化! cin>>c1>>c2; Str_assign(S1,c1);//安排 Str_assign(S2,c2);//安排 //檢驗 安排成功 //Str_traverse(S1); //Str_traverse(S2); Str_concat(T,S1,S2);//拼接 cout<<"After concatting, the T: "; Str_traverse(T); // 比較 T 和 S cout<<"Compare T and S: "<<endl; if(Str_compare(S,T)>0) { cout<<"S > T"<<endl; }else if(Str_compare(S,T)==0) { cout<<"S = T"<<endl; } else if(Str_compare(S,T)<0) { cout<<"S < T"<<endl; } //字串的替換 cout<<endl<<"---------------------"<<endl; cout<<"S: "; Str_traverse(S);//先把S表示出來. cout<<"---------------------"<<endl; cout<<"input string that needs to be replaced in S:"<<endl; //輸入需要被替換的字串 cin>>c1; cout<<"input string that is used to replace in S:"<<endl;//輸入被用來替換的字串 cin>>c2; Str_init(T);//初始化 Str_init(V); //安排 Str_assign(T,c1); Str_assign(V,c2); Str_replace(S,T,V);//V替換T;如果 不存在 V的話 就不用替換了 cout<<"After replacing: "; Str_traverse(S); //copy 功能 無bug /* Str_init(T); Str_copy(T,S); Str_traverse(T); */ //清空 cout<<"clear is coming..."<<endl; Str_clear(S); Str_clear(T); Str_clear(V); Str_clear(S1); Str_clear(S2); Str_clear(Sub); if(Str_empty(S)&&Str_empty(T)&&Str_empty(V)&&Str_clear(S1)&&Str_clear(S2)&&Str_clear(Sub)) { cout<<"Clear succeed"<<endl; } // if(Str_destory(S)&&Str_destory(T)&&Str_destory(V)&&Str_destory(S1)&&Str_destory(S2)&&Str_destory(Sub)) // { // cout<<"Destory succeed"<<endl; // } return 0; }