数据结构| 串

串的定义

串,也称为字符串,是由零个或多个字符组成的有限序列。它是一种特殊的线性表,仅由字符组成。一般记作:

S=”a1a2……an”

其中,S是串名,n是串的长度,用双引号括起来的字符序列是串的值。ai可以是字母、数字和其他字符。当n=0时称为空串。

串的抽象数据类型的定义:

ADT Str{
    数据对象;
    数据关系;

    基本操作:
        StrAssign(&S,cstr[])
            操作结果:将字符串cstr[]的字符赋给S
        StrEmpty(S)
            初始条件:存在串
            操作结果:判断串是否为空,若为空返回1,否则返回0
        StrLength(S)
            初始条件:存在串
            操作结果:返回串的长度
        StrCopy(&T,S)
            初始条件:存在串
            操作结果:将串S的值赋给T
        StrCompare(S,T)
            初始条件:存在串
            操作结果:比较串S和串T每个字符的ASCII值的大小,返回它们的差值
        StrInsert(&S,pos,T)
            初始条件:存在串
            操作结果:将串T从S中第pos个位置开始插入
        StrDelete(&S,pos,len)
            初始条件:存在串
            操作结果:将串S从第pos个位置开始往后删除len个元素
        StrClear(&S)
            初始条件:存在串
            操作结果:将串S清空
}

串的顺序表示与实现

1.宏定义解释

#define MaxLength 60  //串的最大长度

2.结构类型

typedef struct {
    char str[MaxLength];  //数组
    int length;  //长度
}

3.基本操作的实现

(1)串的赋值StrAssign

void StrAssign(SeqString *S,char cstr[]){
    int i=0;
    for(i=0;cstr[i]!='\0';i++){
        S->str[i]=cstr[i];
        S.length=i;
    }
}

(2)判断串是否为空StrEmpty

int StrEmpty(SeqString S){
    if(S.length==0){  //当串为空时返回1
        return 1;
    }
    else{
        return 0;  //否则返回0
    }
}

(3)串的长度StrLength

int StrLength(SeqString S){
    return S.length;
}

(4)复制串StrCopy

void StrCopy(SqeString *T,SeqString S){
    int i;
    for(i=1;i<S.length;i++){
        T->str[i]=S.str[i];
    }
    T->length=S.length;
}

(5)比较串StrCompare

int StrCompare(SeqString S,SeqString T){
    int i;
    for(i=0;i<S.length&&i<T.length;i++){
        if(S.str[i]!=T.str[i]){
            return (S.str[i]-T.str[i]);  //如果不相等则返回二者的差值
        }
        else{
            return (S.length-T.length);  //如果比较完毕则返回二者长度的差值
        }
    }
}

(6)串的插入StrInsert

int StrInsert(SqeString *S,int pos,SqeString T){
//在S中的第pos个位置插入T
    int i;
    if(pos<0||pos-1>S->length){  //插入的位置不正确则返回0
        return 0;
    }
    if(S->length+T.length<=MaxLength){  //若T可以完整的插入到S中
        for(i=S->length+T.length-1;i>=pos+T.length-1;i--){  //将S中pos以后的字符向后移动
            S->str[i]=S->str[i-T.length];
        }
        for(i=0;i<T.length;i++){  //开始插入
            S->str[pos+i-1]=T.str[i];
        }
         S->length=S->length+T.length;  //改变长度
            return 1;
    }
    else if(pos+T.length<=MaxLength){  //T可以完全插入,但是S会被截断
        for(i=MaxLength-1;i>T.length+pos-1;i--){  //将S中pos以后的字符向后移动
            S->str[i]=S->str[i-T.length];
        }
        for(i=0;i<T.length;i++){  //开始插入
            S->str[i+pos-1]=T.str[i];
        }
        S->length=MaxLength;  //设置最长长度
        return 0;
    }
    else{  //T不能完全插入到S中
        for(i=0;i<MaxLength-pos;i++){
            S->str[i+pos-1]=T.str[i];  //开始插入
        }
        S->length=MaxLength;
        return 0;
    }
}

(7)串的删除StrDelete

int StrDelete(SeqString *S,int pos,int len){
//在S中删除pos开始的len个字符
    int i;
    if(pos<0||len<0||pos+len>S->MaxLength){  //如果不合法则返回0
        return 0;
    }
    else{
        for(i=pos+len;i<=S->length-1;i++){  //将未删除的字符串移动到前面去
            S->str[i-len]=S->str[i];
        }
        S->length=S->length-len;  //修改长度
        return 1;
    }
}

(8)清空串StrClear

void StrClear(SeqString *S){
    S->length=0;  //j将长度设置为0
}

串的模式匹配

串的模式匹配也称为子串的定位操作,即查找子串在主串中出现的位置。模式匹配的算法主要有两种:BF算法和KMP算法。

1.BF算法

BF算法的主要思想是:从主串S中的第pos个字符开始与子串T的第一个字符比较,如果相等则继续逐一比较后续的字符;否则从主串的下一个字符开始与子串T的第一个字符开始比较,以此类推。如果在主串S中存在与子串T相等的连续字符序列,则匹配成功,返回子串T中第一个字符在主串S中的位置,否则返回0。

BF算法的代码描述如下:

int BFIndex(SeqString S,int pos,SeqString T){
//从S中的第pos个位置开始查找T
    int i,j;
    i=pos-1;
    j=0;
    while(i<S.length&&j<T.length){
        if(S.str[i]==T.str[j]){  //如果相等,则继续往后寻找
            i++;
            j++:
        }
        else{
            i=i-j+1;   //如果中途断开,则从S的pos的下一个位置开始寻找
            j=0;  //T从头开始比较
        }
    }
    if(j>=T.length){  
        return i-j+1;  //如果找到则返回位置
    }
    else{
        return 0;
    }
}
    原文作者:yzbkaka
    原文地址: https://www.jianshu.com/p/50e755e9e044
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞