1. 程式人生 > >資料結構_字串

資料結構_字串

字串 堆的動態分配 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;
}