本段程序实现串的存储结构是采用堆的动态分配存储表示,并实现了几乎所有常用的串的配套函数
其中逻辑性比较强的就是串的模式匹配算法,在下面的程序中,分别用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个字符之前插入串T bool 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的字串Sub HString 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个字符之前插入串str3 cout<<"在串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; }
原文地址:http://blog.csdn.net/yyc1023/article/details/25563813