分别定义两个结构体——串的定长顺序存储、串的堆式顺序存储
typedef struct
{
char ch[MAXSTRLEN+1];
int length;
}SString;
typedef struct
{
char *ch;
int length;
}HString;
问题:
1、编写函数,串用定长顺序存储表示来实现串的基本操作;
2、 编写串的匹配算法,实现查找功能。
算法思想阐述:
BF算法:首先S[1]和T[1]比较,若相等,则再比较S[2]和T[2],一直到T[M]为止;若S[1]和T[1]不等,则S向右移动一个字符的位置,再依次进行比较。如果存在k,1≤k≤N,且S[k+1…k+M]=T[1…M],则匹配成功;否则失败。
该算法最坏情况下要进行M*(N-M+1)次比较, 时间复杂度为O(M*N)。
一、各函数代码如下
解题一:
//生成串
Status StrAssign(SString &S,char chars[])
{
int i;
S[0]=strlen(chars);
for(i=0;chars[i]!='\0'&&i+1<MAXSTRLEN;i++){
S[i+1]=chars[i];
}
S[i+1]='\0';
return OK;
}
//输出串
void PrintStr(SString S)
{
int i;
for(i=1;i<S[0]+1;i++){
cout<<S[i];
}
cout<<endl;
}
//求串长
Status StrLength(SString S)
{
return S[0];
}
//判空
Status StrEmpty(SString S)
{
if(S[0]==0){
return OK;
}
else{
return FALSE;
}
}
//比较字符串
Status StrCompare(SString S,SString T)
{
int i=0;
for(i=0;i<S[0]&&i<T[0];i++){
if(S[i]!=T[i])
return S[i]-T[i];
}
return S[0]-T[0];
}
//字符串连接:用T返回由S1和S2连接成的新串
Status Concat(SString &T,SString S1,SString S2)
{
int i,j;
if(S1[0]+S2[0]<=MAXSTRLEN){
//未超出用户定义的最大串长
for(i=1;S1[i]!='\0';i++){
T[i]=S1[i];
}
for(j=1;S2[j]!='\0';j++){
T[S1[0]+j]=S2[j];
}
//两次循环连接两串
T[S1[0]+j+1]='\0';
T[0]=S1[0]+S2[0];
}
else if(S1[0]<MAXSTRLEN){
//超出用户定义的最大串长,这里会出现截断情况
for(i=1;S1[i]!='\0';i++){
T[i]=S1[i];
}
for(j=1;j<=MAXSTRLEN-S1[0];i++){
T[S1[0]+j]=S2[j];
}
T[0]=MAXSTRLEN;
}
else{
//条件是S1[0]>MAXSTRLEN,这里仅截断S1
for(i=1;S1[i]!='\0';i++){
T[i]=S1[i];
}
T[i+1]='\0';
T[0]=S1[0];
}
return OK;
}
//取子串:用Sub返回串S的第pos个字符起长度为len的子串
//注意:1<=pos<=StrLength(S),0<=len<=StrLength(S)-pos+1
Status SubString(SString &Sub,SString S,int pos,int len)
{
int i,j;
if(pos<1||pos>S[0]||len<0||len>S[0]-pos+1){
return ERROR;
}
for(i=1,j=pos;i<=len&&j<=pos+len-1;i++,j++){
Sub[i]=S[j];
}
Sub[i+1]='\0';
Sub[0]=len;
return OK;
}
//串的模式匹配:返回子串T(非空)在主串中第pos个字符之后的位置。若不存在,则返回0
Status Index(SString S,SString T,int pos)
{
int i=pos;
int j=1;
while(i<=S[0]&&j<=T[0]){
if(S[i]==T[j]){
++i;
++j;
}else{
i=i-j+2;
j=1;
}
}
if(j>T[0]){
return i-T[0];
}
else return FALSE;
}
//串插入
Status StrInsert(SString& S, int pos, SString T)
{
int i;
if (StrEmpty(T))
return ERROR;
if (pos<1||pos>S[0]+1)
return ERROR;
else
{
for (i=S[0]-1;i>=pos-1;i--)
S[i+T[0]]=S[i];
for (i=0;i<T[0];i++)
S[pos+i-1]=T[i];
S[0] += T[0];
}
return OK;
}
//删除:删除串S指定的位置开始的长度为len的子串
Status StrDelete(SString &S,int pos,int len)
{
int i;
if(pos<1||len>S[0]-pos+1){
return ERROR;
}
for(i=pos+len;i<=S[0];i++){
S[i-len]=S[i];
}
S[0]-=len;
return OK;
}
//串替换
Status Replace(SString &S, SString T, SString V)//最终以S返回
{
int i;
if (StrEmpty(T))
return ERROR;
i = Index(S, T, 1);
while (i != 0)
{
StrDelete(S, i, StrLength(T));
StrInsert(S, i, V);
i += StrLength(V);
i = Index(S, T, i);
}
return OK;
}
//清空串
Status ClearString(SString &S)
{
int i;
for(i=1;S[i]!='\0';i++){
S[i]='\0';
}
S[0]=0;
return OK;
}
解题一完整代码:
#include <iostream.h>
#include <string.h>
#define OK 1
#define ERROR 1
#define FALSE 0
#define MAXSTRLEN 255
typedef int Status;
typedef unsigned char SString[MAXSTRLEN+1];//0号单元存放串的长度
using namespace std;
/*********以下是各类函数的实现*********/
//初始化:0号单元存放串的长度
Status InitStr(SString &S)
{
S[0]=0;
return OK;
}
//生成串
Status StrAssign(SString &S,char chars[])
{
int i;
S[0]=strlen(chars);
for(i=0;chars[i]!='\0'&&i+1<MAXSTRLEN;i++){
S[i+1]=chars[i];
}
S[i+1]='\0';
return OK;
}
//输出串
void PrintStr(SString S)
{
int i;
for(i=1;i<S[0]+1;i++){
cout<<S[i];
}
cout<<endl;
}
//求串长
Status StrLength(SString S)
{
return S[0];
}
//判空
Status StrEmpty(SString S)
{
if(S[0]==0){
return OK;
}
else{
return FALSE;
}
}
//比较字符串
Status StrCompare(SString S,SString T)
{
int i=0;
for(i=0;i<S[0]&&i<T[0];i++){
if(S[i]!=T[i])
return S[i]-T[i];
}
return S[0]-T[0];
}
//字符串连接:用T返回由S1和S2连接成的新串
Status Concat(SString &T,SString S1,SString S2)
{
int i,j;
if(S1[0]+S2[0]<=MAXSTRLEN){
//未超出用户定义的最大串长
for(i=1;S1[i]!='\0';i++){
T[i]=S1[i];
}
for(j=1;S2[j]!='\0';j++){
T[S1[0]+j]=S2[j];
}
//两次循环连接两串
T[S1[0]+j+1]='\0';
T[0]=S1[0]+S2[0];
}
else if(S1[0]<MAXSTRLEN){
//超出用户定义的最大串长,这里会出现截断情况
for(i=1;S1[i]!='\0';i++){
T[i]=S1[i];
}
for(j=1;j<=MAXSTRLEN-S1[0];i++){
T[S1[0]+j]=S2[j];
}
T[0]=MAXSTRLEN;
}
else{
//条件是S1[0]>MAXSTRLEN,这里仅截断S1
for(i=1;S1[i]!='\0';i++){
T[i]=S1[i];
}
T[i+1]='\0';
T[0]=S1[0];
}
return OK;
}
//取子串:用Sub返回串S的第pos个字符起长度为len的子串
//注意:1<=pos<=StrLength(S),0<=len<=StrLength(S)-pos+1
Status SubString(SString &Sub,SString S,int pos,int len)
{
int i,j;
if(pos<1||pos>S[0]||len<0||len>S[0]-pos+1){
return ERROR;
}
for(i=1,j=pos;i<=len&&j<=pos+len-1;i++,j++){
Sub[i]=S[j];
}
Sub[i+1]='\0';
Sub[0]=len;
return OK;
}
//串的模式匹配:返回子串T(非空)在主串中第pos个字符之后的位置。若不存在,则返回0
Status Index(SString S,SString T,int pos)
{
int i=pos;
int j=1;
while(i<=S[0]&&j<=T[0]){
if(S[i]==T[j]){
++i;
++j;
}else{
i=i-j+2;
j=1;
}
}
if(j>T[0]){
return i-T[0];
}
else return FALSE;
}
//串插入
Status StrInsert(SString& S, int pos, SString T)
{
int i;
if (StrEmpty(T))
return ERROR;
if (pos<1||pos>S[0]+1)
return ERROR;
else
{
for (i=S[0]-1;i>=pos-1;i--)
S[i+T[0]]=S[i];
for (i=0;i<T[0];i++)
S[pos+i-1]=T[i];
S[0] += T[0];
}
return OK;
}
//删除:删除串S指定的位置开始的长度为len的子串
Status StrDelete(SString &S,int pos,int len)
{
int i;
if(pos<1||len>S[0]-pos+1){
return ERROR;
}
for(i=pos+len;i<=S[0];i++){
S[i-len]=S[i];
}
S[0]-=len;
return OK;
}
//串替换
Status Replace(SString &S, SString T, SString V)//最终以S返回
{
int i;
if (StrEmpty(T))
return ERROR;
i = Index(S, T, 1);
while (i != 0)
{
StrDelete(S, i, StrLength(T));
StrInsert(S, i, V);
i += StrLength(V);
i = Index(S, T, i);
}
return OK;
}
//清空串
Status ClearString(SString &S)
{
int i;
for(i=1;S[i]!='\0';i++){
S[i]='\0';
}
S[0]=0;
return OK;
}
//主函数
int main(int argc, char *argv[])
{
SString S1,S2,T,Sub,Rep;
int len1,len2,cha,pos,len;
InitStr(T);
InitStr(Sub);
InitStr(Rep);
char s1[100];
char s2[100];
//避免s1.length+s2.length>MAXSTRLEN
cout<<"请输入字符串1:"<<endl;
scanf("%s",s1);
StrAssign(S1,s1);
//PrintStr(S1);
cout<<"请输入字符串2:"<<endl;
scanf("%s",s2);
StrAssign(S2,s2);
cout<<"1.字符串长度 ";
cout<<"2.比较字符串 ";
cout<<"3.取子串 ";
cout<<"4.匹配模式 " ;
cout<<"5.连接字符串 ";
cout<<endl<<"6.字符串的插入 ";
cout<<"7.字符串的替换 ";
cout<<"8.删除子字符串 ";
cout<<"9.清空字符串 ";
cout<<"10.退出程序"<<endl;
int select;
while(true){
cout<<"请选择你想要的功能;"<<endl;
cin>>select;
switch(select){
case 1:
printf("串1的长度是:%d\n",StrLength(S1));
printf("串2的长度是:%d\n",StrLength(S2));
break;
case 2:
cha=StrCompare(S1,S2);
cout<<"两串比较的结果是:";
if(cha>0){
cout<<"S1>S2"<<endl;
}else if(cha<0){
cout<<"S1<S2"<<endl;
}else cout<<"S1=S2"<<endl;
break;
case 3:
int a;
cout<<"请问想对哪个字符串进行取子串操作?(回复1或2)"<<endl;
cin>>a;
if(a==1){
cout<<"输入你想取的S1的子串具体位置和长度:";
cin>>pos>>len;
if(SubString(Sub,S1,pos,len)){
cout<<"串1的第"<<pos<<"个位置开始长度为"<<len<<"的子串Sub为: ";
PrintStr(Sub);
}
else{
cout<<"查找子串失败!"<<endl;
}
break;
}
if(a==2){
cout<<"输入你想取的S2的子串具体位置和长度:";
cin>>pos>>len;
if(SubString(Sub,S2,pos,len)){
cout<<"串2的第"<<pos<<"个位置开始长度为"<<len<<"的子串Sub为: ";
PrintStr(Sub);
}
else{
cout<<"查找子串失败!"<<endl;
}
break;
}
else{
cout<<"输入错误!查找字串失败!"<<endl;
break;
}
case 4:
cout<<"请输入匹配的pos位置:";
cin>>pos;
if(Index(S1,S2,pos)){
cout<<"串2在串1中位置是:"<<Index(S1,S2,pos)<<endl;
}else cout<<"匹配失败!"<<endl;
break;
case 5:
Concat(T,S1,S2);
cout<<"串1和串2连接后的串为:";
PrintStr(T);
break;
case 6:
cout<<"欲实现串2对串1的插入!请输入插入的pos位置:";
cin>>pos;
if(StrInsert(S1,pos,S2)){
PrintStr(S1);
break;
}
case 7:
Replace(Rep,S1,S2);
cout<<"替换成功!";
break;
case 8:
cout<<"请问想对哪个字符串进行删除操作?(回复1或2)"<<endl;
cin>>a;
if(a==1){
cout<<"请输入对S1删除的pos位置和长度:";
cin>>pos>>len;
if(StrDelete(S1,pos,len)){
PrintStr(S1);
}
else{
cout<<"删除失败!"<<endl;
}
break;
}
if(a==2){
cout<<"请输入对S2删除的pos位置和长度:";
cin>>pos>>len;
if(StrDelete(S2,pos,len)){
PrintStr(S2);
}
else{
cout<<"删除失败!"<<endl;
}
break;
}
else{
cout<<"输入错误!删除失败!"<<endl;
break;
}
case 9:
cout<<"请问想对哪个字符串进行清空操作?(回复1或2)"<<endl;
cin>>a;
if(a==1){
if(ClearString(S1)) cout<<"已清空串1!"<<endl;
break;
}
if(a==2){
if(ClearString(S2)) cout<<"已清空串2!"<<endl;
break;
}
else{
cout<<"输入错误!清空失败!"<<endl;
break;
}
case 10:
cout<<"退出程序!";
exit(0);
break;
}
}
}
执行效果:
解题二(在题一基础上稍加修改即可)
/*用回溯法来实现模式匹配算法,寻找模式串t在主串s中从第pos位开始是否出现,若出现则返回第一次出现的位置,否则返回0*/
int StrIndex1(SString s,SString t,int pos)
{
int s, t, i,j;
s = S.length;
t = T.length;
i = pos;
j = 1;
while(i<=S.length && j<=T.length)
{
if(S.ch[i]==T.ch[j]){
++i;++j;}
else{
i=i-j+2;j=1;}
}
if(j>T.length) return i-T.length;
else return 0;
}
/*利用其他函数来实现模式匹配算法*/
int StrIndex2(SString s,SString t,int pos)
{
int m,n,i;
SString sub;
n=StrLength(s);
m=StrLength(t);
i=pos;
while(i<=n-m+1)
{
SubString(sub,s,i,m);
if(StrCompare(sub,t)!=0) ++i;
else return i;
}
return 0;
}
/*用KMP算法来实现模式匹配算法,效率较高*/
int StrIndex_KMP(SString s,SString t,int pos)
{
int i,j;
int next[MAX+1];
i=1;
next[i]=0;
j=0;
while(i<t[0])
{
if(j==0||t[i]==t[j])
{
i++;
j++;
if(t[i]!=t[j]) next[i]=j;
else next[i]=next[j];
}
else j=next[j];
}
i=pos;
j=1;
while(i<=s[0]&&j<=t[0])
{
if(j==0 || s[i]==t[j])
{
i++;
j++;
}
else
j=next[j];
}
if(j>t[0])return i-t[0];
else return 0;
}
执行效果:
分享完毕~文章来源:https://www.toymoban.com/news/detail-425629.html
欢迎小伙伴们在文下评论和私信喔~文章来源地址https://www.toymoban.com/news/detail-425629.html
到了这里,关于【数据结构】串的基本操作及应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!