字符串的堆分配存储,还是有很多疑问,数据结构好难,感觉都是玄学

以后会更新KMP,闲了再更

//堆 动态分配 
//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;
}

 


年轻也需要有所作为( ・´ω`・ )