数据结构 4.1: 串

代码如下:

#include<cstring>
#include<cstdio>
#include<iostream>
#define MAX_SIZE 1000
using namespace std;
typedef char ElemType;
typedef struct Mystr
{

    ElemType *ch;
    int length;//个数
    int size;//空间
} Mystr;

Mystr *CreateStr();

void StrAssign(Mystr *str, ElemType *chars); 

void StrCopy(Mystr *str1, Mystr *str2);  

bool StrEmpty(Mystr *str);

int StrCompare(Mystr *str1,Mystr *str2);

int  StrLength(Mystr *str);

void ClearString(Mystr *str);

Mystr *Concat(Mystr *str1,Mystr *str2); 

Mystr *SubString(Mystr *str,int pos,int len );  

int Index(Mystr *str1,Mystr *str2,int pos); 
void StrInsert(Mystr *str,int pos,Mystr *str1);  

int Index(Mystr *str1,Mystr *str2,int pos); 

void StrDelete(Mystr *str,int pos,int len);  

void Replace(Mystr *str,Mystr *exchanged,Mystr *goexchange); 

Mystr *CreateStr()
{

    Mystr *newstr = new Mystr;
    newstr->length = 0;
    newstr->ch = new ElemType[MAX_SIZE];
    newstr->size = MAX_SIZE;
    return newstr;

}

void StrAssign(Mystr *str, ElemType *chars) 
{

    strcpy(str->ch,chars);

    str->length = strlen(chars);
}

void StrCopy(Mystr *str1, Mystr *str2)  
{
    str1->ch[str1->length] = '\0';

    str2->ch[str2->length] = '\0';

    strcpy(str1->ch,str2->ch);

    str1->length = str2->length;
}

bool StrEmpty(Mystr *str)
{
    if(str->length ==  0)
    {
        return true;//is empty
    }

    return false;
}
int StrCompare(Mystr *str1,Mystr *str2)
{
    str1->ch[str1->length] = '\0';
    str2->ch[str2->length] = '\0';

    return strcmp(str1->ch,str2->ch);
}

int  StrLength(Mystr *str)
{
    return str->length;
}

void ClearString(Mystr *str)
{


    str->length = 0;

}

Mystr *Concat(Mystr *str1,Mystr *str2) 
{

    str1->ch[str1->length] = '\0';
    str2->ch[str2->length] = '\0';


    Mystr *newstr =  new  Mystr;

    newstr->ch = new ElemType[str1->size+str2->size]; 

    newstr->size = str1->size+str2->size;

    newstr->length = str1->length+str2->length;

    strcpy(newstr->ch,str1->ch); 

    strcat(newstr->ch,str2->ch);

    return newstr;

}
Mystr *SubString(Mystr *str,int pos,int len )  
{
    Mystr *newstr =  CreateStr(); 
    int cnt = 0;
    int i,j;
    for(i=pos-1; i<pos-1+len; i++)
    {
        newstr->ch[cnt++] = str->ch[i];
    }
    newstr->length = len;
    return newstr;

}

int Index(Mystr *str1,Mystr *str2,int pos) 
{
    int i,j;
    if(str1->length-pos+1<str2->length)
    {
        return 0; 
    }

    for(i=pos-1; i<str1->length; i++) 
    {

        if(str1->ch[i]==str2->ch[0])
        {
            for(j=1; j<str2->length; j++)
            {
                if(str1->ch[i+j]!=str2->ch[j])
                {
                    break;
                }
            }

            if(j==str2->length)
            {
                return i+1; 
            }
        }

    }
    return 0;
}

void Replace(Mystr *str,Mystr *exchanged,Mystr *goexchange) 
{

    Mystr *tempstr = CreateStr();
    int pos = 1;
    int i=0;
    int cnt = 0;
    int flagi = 0;
    int flag = 0;
    while(true)
    {

        pos = Index(str,exchanged,pos); 

        if(pos == 0)
        {
            break;
        }


        if(pos==1) 
        {
            strcpy(tempstr->ch,exchanged->ch);

            cnt = exchanged->length;

        }
        else
        {

            for(i=flagi; i<pos-1; i++)
            {

                tempstr->ch[cnt++]=str->ch[i];

            }
            i=0;

            while(goexchange->ch[i]!='\0')
            {
                tempstr->ch[cnt++]=goexchange->ch[i]; 
                i++;
            }


        }

        flagi = pos +exchanged->length-1; 
        pos =  pos+exchanged->length; 

    }


    for(i=flagi; i<str->length; i++)
    {

        tempstr->ch[cnt++]=str->ch[i];

    }

    tempstr->ch[cnt]= '\0';

    strcpy(str->ch,tempstr->ch);
    tempstr->length = cnt ;

}

void StrInsert(Mystr *str,int pos,Mystr *str1)  
{
    int i;
    int len = str1->length;
    Mystr *tempstr =  CreateStr();  
    int cnt= 0;
    for(i=0 ; i<pos-1; i++)
    {
        tempstr->ch[cnt++] = str->ch[i]; 
    }
    for(i=0; i<str1->length; i++)
    {
        tempstr->ch[cnt++] = str1->ch[i]; 
    }
    for(i=pos-1; i<str->length; i++)
    {
        tempstr->ch[cnt++] = str->ch[i]; 
    }

    tempstr->ch[cnt] = '\0';

    strcpy(str->ch,tempstr->ch);

    str->length = str->length+str1->length;

}

void StrDelete(Mystr *str,int pos,int len)  
{

    int i;
    Mystr *tempstr =  CreateStr(); 
    int cnt= 0;

    for(i=0; i<pos-1; i++)
    {
        tempstr->ch[cnt++] = str->ch[i]; 
    }

    for(i=pos+len-1; i<str->length; i++)
    {
        tempstr->ch[cnt++] = str->ch[i];
    }
    tempstr->ch[cnt] = '\0';
    strcpy(str->ch,tempstr->ch);
    str->length = str->length-len;


}


int main()
{

    system("color 74");
    cout<<"班级:计算机类2022级一班\r\n"<<"姓名:聂熙\r\n";

    cout<<"数据可自己输入修改也可设置菜单\r\n";
    cout<<"\r\n";
    char chars1[] = {"my name is lan  lan lan"};
    char chars2[] = {"my name is min min min "};
    char chars3[] = {"lan"};

    char chars4[] = {"I is handsome but you is more handsome"};
    int i;
    Mystr *str2 = CreateStr();

    Mystr *str1 = CreateStr();

    Mystr *str3 = CreateStr();

    Mystr *str4 = CreateStr();

    cout<<"测试点1:字符串赋值给串:\n";
    if(StrEmpty(str1)==true)
    {
        cout<<"未赋值时:为空串\n";
    }

    StrAssign(str1, chars1);

    cout<<"赋值成功该串为:" <<str1->ch<<"\r\n"<<endl;

    cout<<"测试点2:串赋值给串:\n";

    StrAssign(str2, chars2);

    cout<<"str1是:"<< str1->ch<<"\r\n"<<"str2是:"<<str2->ch<<"\r\n";

    StrCopy(str1, str2);

    cout<<"将str2赋值给str1后str1是:"<< str1->ch<<"\r\n"<<endl;

    StrAssign(str1, chars1);

    cout<<"测试点3:两个串值的比较:\n";

    cout<<"1串是:"<< str1->ch<<"\r\n"<<"2串是:"<<str2->ch<<"\r\n";

    if(StrCompare(str1,str2)>0)
    {

        cout<<str1->ch<<">"<<str2->ch<<endl;
    }

    else if(StrCompare(str1,str2)==0)
    {
        cout<<str1->ch<<"="<<str2->ch<<endl;
    }

    else
    {
        cout<<str1->ch<<"<"<<str2->ch<<endl;
    }
    cout<<"\r\n";


    cout<<"测试点4:两个串值的连接:\n";

    StrAssign(str4, chars4);
    StrAssign(str2, chars2);
    cout<<"1串是:"<< str2->ch<<"\r\n"<<"2串是:"<<str4->ch<<"\r\n";
    Mystr *stro1 = Concat(str2,str4);
    cout<<"1连接2后是:"<<stro1->ch<<"\r\n"<<endl;


    cout<<"测试点5:返回str的第pos个位置起长度为len的子串的指针\n";

    cout<<"str串是:"<<stro1->ch<<"\r\n";

    int pos,len;
    pos = 3;

    len = 5;
    Mystr *stro2 = SubString(stro1,pos,len );  

    printf("第%d位置,长度为%d的串为%s",pos,len,stro2->ch);

    cout<<"\r\n"<<endl;

    cout<<"测试点6:用goexchange替换主串str中出现的所有与exchanged相等的不重叠的子串\n";


    StrAssign(str4, chars4);
    char chars5[] = {"beautiful"};
    char chars6[] = {"handsome"};
    Mystr *str5 = CreateStr();
    Mystr *str6 = CreateStr();

    StrAssign(str5, chars5);
    StrAssign(str6, chars6);


    cout<<"str 是:"<< str4->ch<<endl;
    cout<<"goexchange 是"<<str5->ch<<endl;
    cout<<"changed 是"<<str6->ch<<endl;

    Replace(str4,str6,str5);

    cout<<"交换后:"<<str4->ch<<endl;
    cout<<"\r\n";

    cout<<"测试点7:在串str的第pos个字符之前插入串str1\n";

    pos = 1;
    char chars7[] = {"I am a girl so "};

    StrAssign(str5, chars7);
    cout<<"原串:"<< str4->ch<<endl;
    cout<<"插入串"<<str5->ch<<endl;
    StrInsert(str4, pos,str5);  

    printf("在第%d位置前插入后 原串为%s:",pos,str4->ch);

    cout<<"\r\n"<<endl;

    char charstemp[]= {"123456789"};
    StrAssign(str4, charstemp);
    cout<<"测试点8:从str中删除第pos字符起长度为len的子串\n";
    cout<<"未删除前:"<<str4->ch<<endl;

    pos = 3;
    len = 4;
    StrDelete(str4,pos,len); 
    printf("从第%d开始删除长度为%d的串结果为:%s",pos,len,str4->ch);
    cout<<"\r\n竣工咯!" ;

    return 0;

}


运行结果:在这里插入图片描述
学习总结:
串是由零个或多个字符组成的有限序列,也就是字符串。在计算机科学中,字符串是一种基本且广泛使用的数据结构,串的操作是求子串、子序列、模式匹配、编辑距离等。
下面是本次学习串的一些总结:
1,串的表示:串可以用字符数组来表示,也可以用字符串类来表示。一般采用后者表示法。
2,串的存储:串的存储可以采用顺序存储和链式存储两种方法。顺序存储效率高,但是插入、删除操作较为复杂。
3.串的操作:串的基本操作有求长度、求子串、子序列、模式匹配、编辑距离等。这些操作均可通过暴力算法和 KMP 等匹配算法来实现。
4.KMP 算法:KMP 算法是一种高效的字符串匹配算法。其核心思想是将模式串和目标串进行匹配,在匹配失败时通过已经匹配成功的前缀和后缀字符相等的最大长度(即 next 数组)来快速调整匹配位置。
总之,串作为计算机科学中基础的数据结构之一,应用广泛,必须掌握其基本操作和常用算法,以应对实际问题的挑战。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值