串(C++实现)

来源:互联网 发布:网络p2p的四条红线 编辑:程序博客网 时间:2024/06/05 08:42

本段程序实现串的存储结构是采用堆的动态分配存储表示,并实现了几乎所有常用的串的配套函数

其中逻辑性比较强的就是串的模式匹配算法,在下面的程序中,分别用BF算法和KMP算法对其进行了

实现。

#include<iostream>using namespace std;struct HString{HString(){ch = 0;length = 0;}char * ch;//字符存储区int length;//串长};void ClearString(HString & T);//用C字符串进行初始化void StrAssign(HString & T,char s[]){free(T.ch);T.length = 0;for(;'\0'!=s[T.length];(T.length)++);T.ch =(char *)malloc(T.length*(sizeof(char)));if(!T.ch) exit(0);for(int i=0;'\0'!=s[i];i++){T.ch[i] = s[i];}}//串的复制void StrCopy(HString & T,HString & S){ClearString(T);T.length = S.length;T.ch = (char*)malloc(T.length*(sizeof(char)));if(!T.ch) exit(0);for(int i=0;i<T.length;i++){T.ch[i] = S.ch[i];}}//串的比较int StrCompare(HString & T,HString & S){for(int i=0;i<T.length&&i<S.length;i++){if(T.ch[i]!=S.ch[i])  return T.ch[i]-S.ch[i];}return T.length - S.length;}//返回串的长度int StrLength(HString & T){return T.length;}//清空串void ClearString(HString & T){free(T.ch);T.length = 0;}//连接两个串构成一个新串void Concat(HString & T,HString & S1,HString & S2){ClearString(T);T.length = S1.length + S2.length;T.ch = (char*)malloc(T.length*(sizeof(char)));if(!T.ch) exit(0);int i = 0;for(;i<S1.length;i++){T.ch[i] = S1.ch[i];}for(int j = 0;j<S2.length;j++,i++){T.ch[i] = S2.ch[j];}}//用Sub串返回S的第pos个字符起长度为len的字串Sub  bool SubString(HString & Sub,HString & S,int pos,int len){if(S.length<(pos+len-1)) return false;Sub.length = len;Sub.ch = (char*)malloc(Sub.length*(sizeof(char)));if(!Sub.ch) exit(0);for(int i = 0;i<len;i++){Sub.ch[i] = S.ch[pos+i-1];}return true;}/*//串的模式匹配//若主串S中存在和串T值相同的字串,则返回它在主串S中第pos个字符之后的第一次出现的位置,否则返回-1*///算法一:BF算法int Index_BF(HString &S,HString &T,int pos){int i = pos ,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 - T.length;else return -1;}//算法二:KMP算法  ---  辅助函数(初始化并发next数组)void Get_next(HString &T,int next[]){ int i = 1,j; next[0] = 0; next[1] = 0; j = next[1]; for(;i<T.length;) { if(0==j||T.ch[i] == T.ch[j]) { if(0==j&&T.ch[i] != T.ch[j])  {next[++i] = j;} else {  next[++i] = ++j; } } else { j = next[j]; } }}//算法二:KMP算法  ---  实现函数 int Index_KMP(HString &S,HString &T,int pos){ int * next = new int[T.length]; Get_next(T,next); int i = pos,j = 0; for(;i<S.length&&j<T.length;) {if(S.ch[i] == T.ch[j])  {     j++; i++;  }   else   {   if(0==j) i++;   else j = next[j];   } } if(j>=T.length) { return i - T.length; } else{return -1; }}//用V替换S中所有与T相等的不重叠的字串//替换的前提是被替换的字符串T和替换的字符串的长度相等  Replace(str2,str3,strV);bool Replace(HString & S,HString &T,HString &V){if(T.length!=V.length) return false;int pos =0;while (pos<S.length){pos = Index_BF(S,T,pos);if(-1==pos) return true;else{for(int i = 0;i<T.length;i++){S.ch[i+pos] = V.ch[i];}pos += V.length;}}}//在串S的第pos个字符之前插入串Tbool StrInsert(HString &S,int pos,HString &T){--pos;if(S.length<pos) return false;HString ss;StrCopy(ss,S);ClearString(S);S.length = ss.length + T.length;S.ch = (char*)malloc(S.length*(sizeof(char)));if(!S.ch) exit(0);int i =0;for(;i<pos;i++){S.ch[i] = ss.ch[i];}for(int j=0;j<T.length;j++){S.ch[i++] = T.ch[j];}for(;pos<ss.length;pos++){S.ch[i++] = ss.ch[pos];}return true;}//从串S中删除第pos个字符起长度为len的字串bool StrDelete(HString &S,int pos,int len){if(S.length<(pos+len-1))return false;HString ss;StrCopy(ss,S);ClearString(S);S.length = ss.length - len;S.ch = (char*)malloc(S.length*(sizeof(char)));if(!S.ch)exit(0);int i = 0;for(;i<pos;i++){S.ch[i] = ss.ch[i];}for(pos = pos+len;pos<ss.length;pos++){S.ch[i++] = ss.ch[pos];}return true;}//遍历访问串中的每一个字符void Visit(HString & T,void(*visit)(char &)){  for(int i = 0;i<T.length;i++)  {   (*visit)(T.ch[i]);  }}//测试函数void fun(char &t){ cout<<t;}int main(){  //创建一个空串HString str;//用C字符串进行初始化      char c[] = "ILOVEYOU";cout<<"用C字符串进行初始化 :str:"<<endl;StrAssign(str,c);//输出Visit(str,fun);cout<<endl;//返回串的长度cout<<"str串的长度是:"<<StrLength(str)<<endl;//串的复制    HString str1;StrCopy(str1,str);cout<<"串的复制 str1:"<<endl;//输出Visit(str1,fun);cout<<endl;//串的比较int s = StrCompare(str,str1);if(s==0){ cout<<"str=str1"<<endl;}if(s>0){ cout<<"str>str1"<<endl;}if(s<0){ cout<<"str<str1"<<endl;}//连接两个串构成一个新串    HString str2;Concat(str2,str,str1);cout<<"连接两个串构成一个新串 str2:"<<endl;//输出Visit(str2,fun);cout<<endl;//用Sub串返回S的第pos个字符起长度为len的字串SubHString str3;cout<<"用Sub串返回S的第7个字符起长度为2的字串str3: "<<endl;SubString(str3,str,7,2);//输出Visit(str3,fun);cout<<endl;//串的模式匹配  查找子串在主串中第一次出现的位置cout<<"BF算法:查找子串str3在主串str1中第一次出现的位置"<<endl;int index = Index_BF(str1,str3,0);if(-1==index){  cout<<"BF算法:未找到子串str3"<<endl;}else{ cout<<"BF算法:查找子串str3在主串str1中第一次出现的下标为:"<<index<<endl;}cout<<"KMP算法:查找子串str3在主串str1中第一次出现的位置"<<endl;int index2 = Index_KMP(str1,str3,0);if(-1==index2){  cout<<"KMP算法:未找到子串str3"<<endl;}else{ cout<<"KMP算法:查找子串str3在主串str1中第一次出现的下标为:"<<index2<<endl;}//用V替换S中所有与T相等的不重叠的字串HString strV;StrAssign(strV,"ZR");cout<<"用“ZR”替换主串Str2中所有的子串str3"<<endl;Replace(str2,str3,strV);//输出Visit(str2,fun);cout<<endl;//在串str2的第pos个字符之前插入串str3cout<<"在串str2的第2个字符之前插入串str3"<<endl;StrInsert(str2,2,str3);//输出Visit(str2,fun);cout<<endl;//从串Str2中删除第pos个字符起长度为len的字串cout<<"从串Str2中删除第2个字符起长度为3的字串"<<endl;StrDelete(str2,2,3);//输出Visit(str2,fun);cout<<endl;}



2 0
原创粉丝点击