大二数据结构4(串,数组,广义表)

一.串

【1】定义

1)是由零个或者多个字符组成的有限序列
2) 记作S=‘a1a2a3 an

  • 串名:s
  • 串值:用单引号括起来的字符序列
  • 长度:串中字符的数目
  • 空串:含有零个字符的串
  • 空格串:由一个或多个空串组合的串
  • 子串:串中任意个连续的字符组合的子序列
  • 字符在串的位置:子串的第一个字符在串中的位置
  • 串相等:当且仅当两个串的值相等,即两个串的长度相等,且对应的字符相等

【2】关于定义的一个例子

1. 子串位置的查找

在这里插入图片描述

2.串的比较

给定两个串: X = ‘ x   1   x   2   … x   n   ’ X=‘x~1~x~2~…x~n~’ X=x 1 x 2 x n  Y = ‘ y   1   y   2   … y   m ⋅ Y=‘y~1~y~2~…y~m· Y=y 1 y 2 y m’,则:

  • n = m n=m n=m x   1   = y   1   , … , x   n   = y   m   x~1~=y~1~,…,x~n~=y~m~ x 1 =y 1 x n =y m 时,称 X = Y X=Y X=Y

  • 当下列条件之一成立时,称X<Y:
    ⑴ $ n<m 且 且 xi=yi(1≤ i ≤ n) $;

    ⑵存在 k ≤ m i n ( m , n ) k ≤ min ( m,n ) kmin(m,n),使得 x   i   = y   i   ( 1 ≤ i ≤ k − 1 ) x~i~=y~i~(1 ≤ i ≤k-1) x i =y i (1ik1) x   k   < y   k   x~k~<y~k~ x k y k 

3.定位函数 Index (S, T, pos)

  • 基本思想:从主串 S S S中取“第 i i i个字符起、长度和串 T T T相等的子串”和串 T T T比较,若相等,
    则求得函数值为 i i i,否则 i i i值增 1 1 1直至找到相等的子串或者不存在和 T T T相等的子串为止。
int index(string s,string t,int pos)
{
    //如果这个子串t不是空,那么查找pos后的有没有相等的子串
    //如果有就开始返回第一个位置
    if(t)
    {
        
        n=stingsize(s);
        m=stringsize(t);
        i=pos;
       while(i<n-m+1)
        {
            substring(s,i,m);//将s从第i位取出m大小的子串
            if(strcompare(sub,t)!=0)
                i++;//如果不是0,那么向后移一位继续查找
            else return i;//如果是0这次找到了,就返回子串的位置
            
        }
    }
}

【3】串的表示与实现

1.串的定长顺序存储表示

  • 用一组地址连续的存储单元存储串值的字符序列
  • 可用定长数组描述:
#define MAXSTRLEN 255;
typedef unsigned char SString[MAXSTRLEN +1]

在这里插入图片描述

2.两串相连

Status Concat(SString &T,SString S1,SString S2){
// 以T返回由S1和S2联接而成的新串,若未截断,返回TRUE,否则FALSE
if(S1[0]+S2[0]<=MAXSTRLEN){ //未截断
T[1..S1[0]]=S1[1..S1[0]];
T[S1[0]+1..S1[0]+S2[0]]=S2[1..S2[0]];
T[0]= S1[0]+S2[0];
uncut=TRUE;
}
else if (S1[0]<MAXSTRSIZE){ //截断
T[1..S1[0]]=S1[1..S1[0]];
T[S1[0]+1..MAXSTRLEN]=S2[1..MAXSTRLEN-S1[0]];
T[0]= MAXSTRLEN;
uncut=FALSE;
}
else { //截断 (仅取S1)
T[0.. MAXSTRLEN]=S1[0.. MAXSTRLEN];
uncut=FALSE;
}
return uncut;
} // Concat

3.求子串

Status SubString (SString &Sub,SString S,int pos,int len ){
//以Sub带回串S中第pos个字符起长度为len的子串
//其中,1≤pos≤StrLength(S) 且0≤len≤StrLength(S)-pos+1
if ( pos<1 || pos>s[0] || len<0 || len > s[0]-pos+1)
return ERROR; 
Sub[1..len] = S[pos..pos+len-1];
Sub[0] = len;
return OK;
} // SubString

【4】串三种储存

1.串的顺序储存

typedef struct {
char ch[MAX]; 
int length; // 串长度
} HString;

2.串的堆式储存

typedef struct {
char *ch; 
int length; // 串长度
} HString;
status strassign(hstring &t,char *chars) {
//生成一个其值等于串常量chars的串t
if(t.ch) free(t.ch);
for(i=0,c=chars; c ;++i,++c);
if(!i) { t.ch=NULL; t.length=0; }
else{
if(!(t.ch=(char *)malloc(I*sizeof(char)))) exit(overflow); 
t.ch[0..i-1]=chars[0..i-1];
t.length=i; }
return OK; }

3.串的块链存储表示

【1】可采用链表方式存储串值,每个结点可以存放一个字符,也可以存放
多个字符 (如图所示)。
在这里插入图片描述

//串的块状储存
#define CHUNKSIZE 80//可由用户定义的块大小
typedef struct chunk{
    char ch[CHUNKSIZE];
    struct chunk  *next;
}chunk;
typedef struct{

   chunk *head,*tail;//串的头尾
   int cuirlen;//串的长度

}

【2】储存密度
存储密度=串值所占的存储位/实际分配的存储位。

【5】串的N中应用

1. 模式匹配Index()

详见上述

2.BF算法

1)基本思想

A. 从主串 s s s中的第一个字符开始和模式 T T T的第一个字符进行比较,

  • 若相等,则继续比较两者的后序字符
  • 若不相等,则从主串的第二个字符开始与模式T的第一个字符进行比较

B.重复上述过程

  • T T T中的字符全部比较完毕,则说明本躺匹配成功

  • S S S中的字符全部比较完,说明匹配失败

2)缺点
A. 算法的一次执行时间不容忽视:问题规模通常很大,常常需要在大量信息中进行匹配;
B. 算法改进所取得的积累效益不容忽视:模式匹配操作经常被调用,执行频率高。
3)算法过程
在这里插入图片描述
4)算法

//BF算法
void BP(sstring &t,sstring s,int pos)
{   i=pos;j=1;//i表示为在s中开始的地方(如果没有要求就为1)
              //j表示子串T开始的地方
    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 0;  
}

5)复杂度
A. 最坏情况:不成功匹配都发生在串T的最后一个字符。
在这里插入图片描述
B.最好情况:不成功匹配都发生在串T的第1个字符在这里插入图片描述

3.KMP算法

void get_next() {
    next[0] = -1;
    int i = 0, j = -1;
    int len = strlen(T);
    while(i < len) {
        if(j == -1 || T[i] == T[j])
            next[++i] = ++j;
         else
            j = next[j];
    }
}
bool KMP() {
    get_next();
    int len1 = strlen(T);
    int len2 = strlen(S);
    int i = 0, j = 0;           //i指向模式串T,j指向主串S
    while(j < len2) {
        if(T[i] == S[j]) {
            i++;
            j++;
            if(i == len1) {
                return true;
            }
        } else {
            i = next[i];
            if(i == -1) {
                j++;i++;
            }
        }
    }
    return false;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值