【数据结构】从0开始数据结构学习-串

本节为串内容,回到总目录:点击此处

字符串

·子串、主串、子串在主串中的位置、串相等
抽象数据类型定义

ADT String
{
    数据对象:
    结构关系:
    基本操作:
    {
        StrAssign(S,chars)
        生成一个值等于chars的串S
        StrInsert(S,pos,T)
        在串S的第pos个字符之前插入串T,1<=pos<=len+1
        StrDelete(S,pos,len)
        从串S中删除第pos个字符起长度为len的子串
        StrCopy(S,T)
        由串T复制得到串S
        StrEmpty(S
        判断是否为空串
        StrCompare(S,T)
        判断S与T的大小
        StrLength(S)
        返回串的长度
        StrClear(S)
        将串清空为空串
        StrCat(S,T)
        将串T的值连接在串S的后面
        SubString(Sub,S,pos,len)
        用Sub返回串S的第pos个字符起长度为len的子串
        StrIndex(S,pos,T)
        若串S中存在和串T相同的子串,则返回它在串S中第pos个字符之后第一次出现的位置,否则返回0
        StrReplace(S,T,V)
        用V替换串S中出现的所有与T相等的不重叠的子串
        StrDestroy(S)
        销毁串S
    }
}
串的存储实现

定长顺序串

#define Maxlen 40
typedef struct
{
    char ch[Maxlen];
    int len;
}SString;
定长顺序串的操作

·顺序串插入函数

分析:在进行顺序串的插入时,插入位置pos将原来的串分成了两个部分A,B长度为LA,LB;以及待插入的部分C,长度为LC。
需要分三种情况讨论
LA+LB+LC <= Maxlen;
LB需要删除一部分
LC需要删除一部分

StrInsert(SString *s, int pos, SString t)
{
//在串s中下标为pos的字符之前插入串t
    int i;
    if (pos < 0 || pos > s -> len) return 0;//检查插入位置是否合法
    if (s -> len+t.len <= Maxlen) //情况1
    {
        for(i = s -> len + t.len - 1;i >= t.len+pos;i --)
        {
            s -> ch[i] = s -> ch[i - t.len];
        }
        for (i = 0; i < i.len; i ++)
        {
            s -> ch[i+pos] = t.ch[i];
            s -> len = s -> len + t.len;
        }
    }
    else if(pos+t.len <= Maxlen) //情况2,
    {
        for(i = Maxlen - 1;i > t.len + pos - 1;i --)
        {
            s -> ch[i] = s -> ch[i - t.len];
        }
        for (i = 0; i < t.len; i ++)
        {
            s -> ch[i + pos] = t.ch[i];
            s -> len = Maxlen;
        }
    }
    else //情况3
    {
        for (i = 0; i < Maxlen - pos;i ++)
        {
            s -> ch[i+pos] = t.ch[i];
            s -> len = Maxlen;
        }
    }
    return 1;
}

·顺序串删除函数

StrDelete(SString *s, int pos, int len)
{
    int i;
    if(pos < 0 || pos > (s -> len - len)) return 0;
    for (i = pos + len; i < s -> len; i ++)
    {
        s -> ch[i - len] = s -> ch[i];
    }//从pos+len开始至串尾依次向前移动,实现删除len个字符
    s -> len = s -> len - len;
    return 1;
}

·串比较函数

StrCompare(SString s,SString t)
{
//如果s、t相等则返回0;若s>t则返回正数,如果s<t则返回负数
    int i;
    for (i = 0; i < s.len && i < t.len; i ++)
    {
        if(s.ch[i] != t.ch[i]) return (s.ch[i] - t.ch[i]);
    }
    return (s.len - t.len); 
}

·定位函数【重点】
1、串的简单模式匹配(布鲁特-福斯)算法
简单模式匹配算法是一种带回溯的匹配算法

从主串S的第pos个字符开始,和模式串T的第一个字符开始比较,如果相等则继续比较后续字符,如果不等,则从(回溯到)主串S的第pos+1个字符开始重新和模式串T比较,直到模式T中的每一个字符都和主串S中的一个连续字符序列全部相等
----插入图片

StrIndex(SString s, int pos, SString t)
{
//从主串S的第pos个字符开始,串t第一次出现的位置
    int i,j,start;
    if(t.len == 0 ) return 0; 
    start = pos; //主串从pos开始
    i = start; 
    j = 0; //模式串从头0开始
    while(i < s.len && j < t.len)
    {
        if(s.ch[i] == t.ch[i]) {i++;j++}  //字符相等时推进
        else //字符不等时回溯
        {
            start ++;
            i = start; //主串从START+1开始
            j = 0; //子串从0开始
        }
    }
    if(j >= t.len) return start;
    else return -1;
}
//另外的写法:使用C语言的库函数
int index(SString s,SString t, int pos)
{
    if(pos > 0)
    {
        n = strlen(s);
        m = strlen(m);
        i = pos;
    }
    while(i < n - m + 1)
    {
        substr(sub , s, i, m);
        if(strcmp(sub,t) != 0) ++i;
        else return i;
    }
    return 0;
}

无回溯的定位匹配算法KMP算法!效率更高

堆串

-字符串包括串名和串值两个部分。串值采用堆串的存储方式存储,串名用符号表存储-
·堆串存储方法:存储空间时在程序执行过程中动态分配的
·串名符号表:所有串名的存储映像构成一个符号表。借助此结构可以在串名与串值之间建立一个对应关系,称为串名的存储映像。
·堆的存储表示:C语言中已有一个称为“堆”的自由存储空间,并可用malloc和free完成动态存储管理

typedef Data_Structure
{
    char *ch;
    int len;
}HString;

堆串与定长顺序串的区别在于:一个长度固定,一个是动态申请的。

·堆串的插入函数

StrInsert(HString *s, int pos, HString *t)
{
    int i; char *temp;
    if (Pos)  //判断插入位置
    temp = (char *) malloc(sizeof(s -> len + t -> len)); //动态产生足够空间
    if(temp == NULL) return false;
    for(i = 0 ;i < pos; i ++) temp[i] = s -> ch[i];
    for(i = 0 ;i < t -> len ; i ++) temp[i+pos] = t -> ch[i];
    for(i = pos; i < s -> len; i ++) temp[i + t -> len] = s -> ch[i];
    s -> len += t -> len;
    free(s -> ch);
    s -> ch = temp;
    return 1;
}

·堆串赋值函数

StrAssign(HString *s, char * tval)
{
    int len, i = 0;
    if(s -> ch != NULL) free(s -> ch);
    while(tval [i] != '\0') i ++;
    len = i;
    if(len)
    {
        s -> ch = (char*) malloc(len);
        if(s -> ch == NULL) return false;
        for(i = 0; i < len; i++) s -> ch[i] = tval[i];
    }
    else
    {
        s -> ch = NULL;
    }
    s -> len = len;
    return 1;
}
块链串

利用链表来存放字符串,一个结点既可以一个字符也可以多个字符。
定义:

#define BLOCK_SIZE 4
typedef struct Block
{
    char ch[BLOCK_SIZE];
    struct Block * next;
}Block;
typedef struct
{
    Block *head;
    Block *tail;
    int len;
}BLString;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值