第四章 串

一、串数据类型的定义

1.定义和存储结构

char str[]="abcdef";
//定长顺序存储
typedef struct
{
    char str[maxSize+1];//加1是为了多出一个用来存储'\0'作为结束标记
    int length;
}Str;
//变长分配存储
typedef struct
{
    char *ch;
    int length;
}Str;

2.串的基本操作

//1.赋值
int strassign(Str& str,char* ch)
{
    if(str.ch)free(str.ch)    //释放原数组空间
    int len=0;
    char *c=ch;               //c指向ch
    while(*c)                 //求串的长度
    {
        ++len;
        ++c;
    }
    if(len==0)
    {
        str.ch=NULL;
        str.length=0;
        return 1;
    }
    else
    {
        str.ch=(char*)malloc(sizeof(char)*(len+1));
        if(str.ch==NULL)return 0;
        else
        {
            c=ch;
            for(int i=0;i<=len;++i,++c)str.ch[i]=*c;
            str.length=len;
            return 1;
        }
    }
}
//strassign(str,"cur input")

//2.取串的长度
int strlength(Str str)
{
    return str.length;
}

//3.串比较操作
int strcompare(Str s1, Str s2)
{
    for(int i;i<s1.length&&i<s2.length;++i)
    {
        if(s1.ch[i]!=s2.ch[i])return s1.ch[i]-s2.ch[i];
        return s1.length-s2.length;
    }
}

//4.串连接操作
int concat(Str &str, Str str1, Str str2)
{
    //如果str不为空,则释放str空间
    //如果为空,则返回0,也就是不能进行串操作
    if(str.ch)
    {
        free(str.ch);
        str.ch=NULL;
    }
    str.ch=(char*)malloc(sizeof(char)*(str1.length+str2.length+1));
    if(str.ch==NULL)return 0;
    int i=0;
    while(i<str1.length)
    {
        str.ch[i]=str1.ch[i];
        ++i;
    }
    int j;
    while(j<=str2.length)
    {
        str.ch[i+j]=str2.ch[j];
        ++j;
    }
    str.length=str1.length+str2.length;
    return 1;
}

//5.求子串操作
//从pos处开始,长度为len的子串
int substring(Str& substr, Str str, ingt pos,int len)
{
    if(pos<0||pos>=str.length||len<0||len>str.length-pos)return 0;
    if(substr.ch)
    {
        free(substr.ch);
        substr.ch=NULL;
    }
    if(len==0)
    {
        substr.ch=NULL;
        substr.length=0;
        return 1;
    }
    else
    {
        substr.ch=(char*)malloc(sizeof(char)*(len+1));
        int i=pos;
        int j=0;
        while(i<pos+len)
        {
            substr.ch[j]=str.ch[i];
            ++i;
            ++j;
        }
        substr.ch[j]='\0';
        sunstr.length=len;
        return 1;
    }
}

//6.串清空操作
int clearstring(Str& str)
{
    if(str.ch)
    {
        free(str.ch);
        str.ch=NULL;
    }
    str.length=0;
    return 1;
}

二、串的模式匹配算法

1.简单模式匹配算法

//对一个串中的定位操作称为串的模式匹配
//其中串中字符存放在1-length的位置上
int index(Str str,Str substr)
{
    int i=1,j=1,k=i;
    while(i<=str.length&&j<=str.length)
    {
        if(str.ch[i]==substr.ch[j])
        {
            ++i;
            ++j;
        }
        else
        {
            j=1;
            i=++k;
        }
    }
    if(j>substr.length)return k;
    else return 0;  
}

2.KMP算法

//思路:每当发生模式串不匹配的情况,先找出发生不匹配的字符pj,取其子串F=p1p2p3...Pj-1
//将模式串后移,使F最先发生前部(FL)和后部(FR)相重合的位置,即模式串后移的目标位置
//即j指向的F前后重合的子串的长度+1(FL和FR的长度加1),可以定义一个next[j]数组,取j=1~m
//m为模式串长度,表示模式串中第j个字符发生不匹配时,应从next[j]处的字符开始重新发生与主串比较

//求next数组:
//next[j]已知,t为当前F最长相等前后缀长度(即FL和FR的长度next[j]=t)
//当pj=pt,则next[j+1]=t+1;
//当pj!=pt,则t=next[t];
void getnext(Str substr, int next[])
{
    int j=1,t=0;next[1]=0;
    while(j<substr.length)
    {
        if(t==0||substr.ch[i]==substr.ch[t])next[++j]=++t;
        else t=next[t];
    }
}

//得到next数组之后,可以将简单算法改进成著名的KMP算法
int KMP(Str str, Str substr, int next[])
{
    //假设从下标为1开始存储的字符
    int i=1, j=1;
    while(i<=str.length&&j<=substr.length)
    {
        if(j==0||str.ch[i]==substr.ch[j])
        {
            ++i;
            ++j;
        }
        else j=next[j];
    }
    if(j>substr.length)retrun i-substr.length;
    else return 0;
}

3.KMP算法的改进

//当j=1时,nextva[j]=0,作为特殊标记
//pj!=pk时,nextval[j]=next[j]=k;
//pj=pk时,nextval[j]=nextval[next[j]]=nextval[k];
void getnextval(Str substr,int nextval[])
{
    int i=1,j=0;
    nextval[1]=0;
    while(i<substr.length)
    {
        if(j==0||substr.ch[i]==substr.ch[j])
        {
            ++i;
            ++j;
            // 加了这两句
            if(substr.ch[i]!=substr.ch[j])nextval[i]=j;
            else nextval[i]=nextval[j];
        }
        else j=nextval[j];
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值