字符串
堆的动态分配
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;
}