掌握串的基本操作、初始化字符串 生成一个值为chars常量串的字符串S、返回字符串的长度、复制字符串、比较两个字符串、将字符串清为空串,并释放该字符串所占空间、在串S1的第pos个字符之前插入串S2、删除主串中指定位置之后一定长度的子串、用T返回由S1和S2联接而成的新串、用T返回串S的第pos个字符起长度为len的子串、返回子串T在主串S中第pos个字符之后的位置、用KMP算法实现返回子串T在主串S中第pos个字符之后的位置、遍历串S;
#include <iostream>
#include <vector>
#define MAXSIZE 50
using namespace std;
typedef struct {
char ch[MAXSIZE+1];
int length;
}TString,*HString;
HString InitString();//初始化字符串
bool StrAssign (HString S,char chs[]);//生成一个值为chars常量串的字符串S
int StrLength(HString S);//返回字符串的长度
bool StringCopy(HString S1,HString S2);//将串S2复制到S1
int StrCompare(HString S,HString T);//比较两个字符串,若S>T,则返回值>0; 若S<T,则返回值<0 ;若S=T,则返回值=0
bool ClearString(HString S);//将S清为空串,并释放S所占空间
bool StrInsert(HString S1,HString S2,int pos);//在串S1的第pos个字符之前插入串S2
bool DeleteString(HString S,int pos,int len);//删除主串中指定位置之后一定长度的子串
bool Concat(HString T,HString S1,HString S2);//用T返回由S1和S2联接而成的新串
bool SubString(HString T,HString S,int pos,int len);//用T返回串S的第pos个字符起长度为len的子串
int Index(HString S,HString T,int pos);//返回子串T在主串S中第pos个字符之后的位置,若不存在,则函数值为0
vector<int> getNext(HString T); //next数组的实现
int Index1(HString S,HString T,int pos);//用KMP算法实现返回子串T在主串S中第pos个字符之后的位置,若不存在,则函数值为0
bool traverString(HString S);//遍历串S
int main(){
cout << "请输入一串字符串" << endl;
char ch[MAXSIZE];
cin >> ch;
HString S = InitString();
if(StrAssign(S,ch)){
cout << "字符串S赋值成功" << endl;
traverString(S);
}
cout << "请输入一串字符串" << endl;
char ch1[MAXSIZE];
cin >> ch1;
HString S1 = InitString();
if(StrAssign(S1,ch1)){
cout << "字符串S1赋值成功" << endl;
traverString(S1);
}
cout << "S字符串长度为" << StrLength(S) << endl;
HString S2 = InitString();
if(StringCopy(S2,S)){
cout << "字符串S2复制S成功" << endl;
traverString(S2);
}
cout << "字符串S1和S2比较大小" << endl;
int m = StrCompare(S1,S2);
if(m==0){
cout << "字符串S1等于S2" << endl;
}
else if(m>0){
cout << "字符串S1大于S2" << endl;
}
else if(m<0){
cout << "字符串S1小于S2" << endl;
}
cout << "请分别输入要插入的字符串和插入字符串S的位置" << endl;
char ch2[MAXSIZE];
int n;
cin >> ch2 >> n;
HString S3 = InitString();
StrAssign(S3,ch2);
StrInsert(S,S3,n);
traverString(S);
int k,p;
cout << "请分别输入在S中要删除的指定位置之后的子串的位置及子串的长度" << endl;
cin >> k >> p;
if(DeleteString(S,k,p)){
cout << "删除成功" << endl;
traverString(S);
}
cout << "请分别输入串S的子串的起始位置和长度" << endl;
cin >> k >> p;
HString T = InitString();
if(SubString(T,S,k,p)){
cout << "子串获取成功" << endl;
traverString(T);
}
HString S4 = InitString();
Concat(S4,S1,S2);
cout << "S1和S2串联而成新串S4" << endl;
traverString(S4);
char ch3[MAXSIZE];
int i;
cout << "请分别输入S1的子串和从主串中查找子串的起始位置" << endl;
cin >> ch3 >> i;
HString S5 = InitString();
StrAssign(S5,ch3);
cout << "子串在主串中的位置为" << Index(S1,S5,i) << endl;
cout << "用KMP算法求";
cout << "子串在主串中的位置为" << Index1(S1,S5,i) << endl;
ClearString(S);
ClearString(S1);
ClearString(S2);
ClearString(S3);
ClearString(S4);
ClearString(S5);
return 0;
}
//初始化字符串
HString InitString(){
HString str= new TString;
if(!str)
cout << "动态内存分配失败!" << endl;
str->length=0;
return str;
}
//生成一个值为chars常量串的字符串S
bool StrAssign (HString S,char chs[]){
int i=0;
while(chs[i])
{
S->ch[S->length++]=chs[i++];
}
return true;
}
//返回字符串的长度
int StrLength(HString S){
return S->length;
}
//将串S2复制到S1
bool StringCopy(HString S1,HString S2){
for(int i=0;i<S2->length;i++){
S1->ch[i] = S2->ch[i];
}
S1->length = S2->length;
return S1;
}
//比较两个字符串,若S>T,则返回值>0; 若S<T,则返回值<0 ;若S=T,则返回值=0
int StrCompare(HString S,HString T){
for(int i=0;(i<S->length)&&(i<T->length);++i){
if(S->ch[i] != T->ch[i])
return (int)(S->ch[i])-(int)(T->ch[i]);
}
return (int)(S->length)-(int)(T->length);
}
//将S清为空串,并释放S所占空间
bool ClearString(HString S){
if(S){
delete S;
}
S->length = 0;
return true;
}
//在串S1的第pos个字符之前插入串S2
bool StrInsert(HString S1,HString S2,int pos){
if(pos<1||pos>S1->length){
cout << "输入错误" << endl;
return false;
}
for(int i=(S1->length-1);i>=pos-1;i--){
S1->ch[i+S2->length] = S1->ch[i];
}
int k = pos-1;
for(int j=0;j<S2->length;j++)
S1->ch[k++] = S2->ch[j];
S1->length += S2->length;
return true;
}
//删除主串中指定位置之后一定长度的子串
bool DeleteString(HString S,int pos,int len)
{
if(pos<1||pos>S->length||len+pos-1>S->length)
{
cout << "输入错误";
exit(-1);
}
int i;
for(i=pos+len;i<=S->length;i++)
{
S->ch[i-len]=S->ch[i];
}
S->length=S->length-len;
return true;
}
//用T返回由S1和S2联接而成的新串
bool Concat(HString T,HString S1,HString S2){
for(int i=0;i<S1->length;i++){
T->ch[i] = S1->ch[i];
}
T->length = S1->length;
int j=0;
while(T->length!=S1->length+S2->length){
T->ch[T->length++] = S2->ch[j++];
}
return true;
}
//用T返回串S的第pos个字符起长度为len的子串
bool SubString(HString T,HString S,int pos,int len){
if(pos<1||pos>S->length||len<0||len>S->length-pos+1)
return false;
if(!len){
T->ch[0] = '\0';
T->length = 0;
}
else{
for(int i=0;i<len;i++){
T->ch[i] = S->ch[pos-1+i];
T->length = len;
}
}
return true;
}
//返回子串T在主串S中第pos个字符之后的位置,若不存在,则函数值为0
int Index(HString S,HString T,int pos){
if(S->length<T->length)
return 0;
if(pos<1||pos>S->length){
cout << "输入错误" << endl;
return 0;
}
for(int i=pos;i<S->length;i++){
int i1 = i;
int i2 = 0;
while(i2<S->length){
if(S->ch[i1]==T->ch[i2]){
i1++;
i2++;
}
else
break;
}
if(i2==T->length)
return (i+1);
}
return 0;
}
//next数组的实现
vector<int> getNext(HString T){
vector<int> next(T->length);
if(T->length==0)
return next;
if(T->length==1){
next[0] = -1;
return next;
}
next[0] = -1;
next[1] = 0;
for(int i=2;i<T->length;i++){
int j = next[i-1];
while(j>=0&&T->ch[i-1]!=T->ch[j]){
j = next[j];
}
if(j==-1)
next[i] = 0;
else
next[i] = j+1;
}
return next;
}
//用KMP算法实现返回子串T在主串S中第pos个字符之后的位置,若不存在,则函数值为0
int Index1(HString S,HString T,int pos){
if(pos<1||pos>S->length){
cout << "输入错误" << endl;
return 0;
}
int i1 = pos;
int i2 = 0;
vector<int> next = getNext(T);
while(i1<S->length&&i2<T->length){
if(S->ch[i1] == T->ch[i2]){
i1++;
i2++;
}
else if(i2==0){
i1++;
}else{
i2 = next[i2];
}
}
return i2 = T->length?(i1-i2+1):0;
}
//遍历串S
bool traverString(HString S){
if(S->length == 0){
cout << "此串为空" << endl;
return false;
}
cout << "此时该字符串为";
for(int i=0;i<S->length;i++){
cout << S->ch[i];
}
cout << endl;
return true;
}