字符串、数组和特殊矩(数据结构)

第四章 字符串、数组和特殊矩阵

4.1字符串

  • 字符串是由0个或多个字符构成的有限序列。
  • 串中所含字符串的个数n称为字符串的长度;当n=0时。字符串为一空串
  • 两个字符串相等,当且仅当两个串的长度相等,并且各个对应位置的字符都相等。
  • 若S=“ ”,此时s由一个空格字符组成,其长度为1,它不等价于空串,因为空串的长度为0.

字符串是一种特殊的线性表,由于线性表有顺序存储和链式存储两种基本的存储结构,因此字符串也有两种基本的存储结构:顺序串和链式串

4.2字符串的模式匹配

寻找字符串p在字符串t中首次出现的位置称为字符串的匹配模式,其中,称p为模式,t为正文,t的长度远远大于p的长度。

4.2.1朴素的模式匹配算法

基本思想:用p中的每个字符去与t中的字符一一比较,其中,n代表正文t的长度,m为模式p的长度。如果t1=p1,t2=p2,…,tm=pm,则模式匹配成功,此时返回起始位置即可;否则,将p向右移动一个字符串的位置,重新开始比较。(就是一个一个比较,比较不到再找下一个)。

时间复杂度为O(n*m)

算法如下:

int index(seqstring p,seqstring t)
{
    
    
    int i,j,succ;
    i=0;succ=0   /*用i扫描正文t,succ为匹配成功的标志*/
    while((i<=t.length-p.length)&&(!succ))
    {
    
    
        j=0;succ=1;    /*用j扫描模式p*/
        while((j<=p.length-1)&&succ)
            if(p.str[j]==t.str[i+j])
                j++;
        	else 
                succ=0;
        i++;
    }
    if(succ)
        return (i-1);
    else
        return (-1);
}

4.2.2快速模式匹配算法(KMP算法)

算法的时间复杂度为O(n+m)

KMP算法基本思想如下:

假设以i和j分别指示正文i和模式p中正待比较的字符,令i、j的初值为0;若在匹配过程中ti=pj,则i与j分别加1;否则i不变,而j退到next的位置继续比较(即j=next【j】);若相等,则指针各自增加1;否则j再退到下一个next【j】值的位置,以此类推,直至下列两种可能之一出现:

  • j退到某个next值时,ti与pj字符比较相等,则i,j指针各自增加1后各自比较
  • j退到-1(即模式的第一个字符“失配”),此时需要将正文指针i向右滑动一个位置,即从正文的下一个字符ti+1起和模式p重新从头开始比较。

在这里插入图片描述

4.3数组

数组本身也是线性表的推广,数组的每个元素由一个值和一组下标确定,在数组中,对于每组有定义的下标都存在一个与之相对应的值。

  • 当把二维数组看作是线性表时,他的每一个结点又是一个向量(一维数组)。
  • 对于三维数组,也可以将它看成是一个线性表。当把三维数组看成是线性表结构时,它的每个元素均由一个二维数组构成。例如,对于三维数组A [m][n][l],我们可以把它看成是一个由m个元素构成线性表,线性表的每个元素是一个n*l的矩阵。

数组是一个具有固定数量数据元素的有序集合。由于数组本身的大小是固定的,因而对数组本身不能执行删除和添加操作,通常除了数组初始化和销毁数组的操作外,只有访问数组元素和改变数组元素的值这两种运算。

4.3.3 数组的存储顺序的实现

存储空间中存储单元是一维的结构,故必须约定一个元素的存储次序,以方便将来对数组元组的存取。

主要分为两大类

  1. 按行优先存储
  2. 按列优先存储

所谓按行优先存储,其基本思想是:从第一行的元素开始按顺序存储,第一行的元素存储完成后,再按顺序存储第2行的元素,然后依次存储第3,…行,直到最后一行所有的元素存储完毕为止。按列存储的基本思想也是一样的。

一个栗子

对于二维数组A [m] [n] :

假设数组中每一个元素占用L个存储单元,若考虑按行优先存储的方式,则上述A数组中任何一个元素aij的存储位置可以按以下公式确定:

*address(aij)= address(a00)+(i * n+j)L

address(a00)表示数组A的首地址,即第一个元素a00的地址,i*n+j表示在元素aij之前已经存放了完整的前i行中的所有元素以及第i+1行的前j个元素。

若按列优先:则数组中任何一个元素aij存储位置的地址计算公式为:

address(aij)= address(a00)+(j * m+i) * L

4.4特殊矩阵

在数值分析的过程中经常遇到一些特殊的矩阵,他们的阶数很高,同时矩阵中包含许多相同的值或零,如对称矩阵、三角矩阵、带状矩阵和稀疏矩阵等。

压缩存储:多个相同值的结点只分配一个存储空间,值为零的结点不分配内存空间。

4.4.1对称矩阵的压缩存储

如果矩阵的行数和列数相等,则称该矩阵为方阵。若n*n阶的方阵A满足:

aij=aji(0<= i <=n-1,0<=j <=n-1)

则称矩阵A为对称矩阵。

在存储时只需要存储对角线以上或对角线以下的部分,未存储部分的元素可以利用元素之间的对称性来访问。

若采用按行优先的存储方式,则数组A对角线以下部分中任何一个数组元素aij(i>=j)的存储地址为:

  1. **address (aij) = address(a00) + [ (1+2+…+i) + j ]L = address(00) + [ i * (i+1)/2 + j ]L ( i>=j )
  2. **address (aij) = address(a00) + [ (1+2+…+i) + j ]L = address(00) + [ j * (j+1)/2 + i]L (i<j)

简单来说。就是乘以大的,加上小的。

4.4.2三角矩阵的压缩存储

这类矩阵,其对角线以下(或以上)部分元素值均为0,故称为上三角矩阵(或下三角矩阵)。

1、下三角矩阵

对矩阵A只需存储对角线以下的部分即可。还是按行优先存储。

则A中下三角部分任何一个元素aij(i>=j)压缩存储后的地址计算公式为:

address(aij)=address(a00)+【i * (i+1) /2 +j】 L*

与对称矩阵不同的是,当 i < j 时,aij的值为0 ,其没有对应的存储空间

2、上三角矩阵

矩阵A为n*n的矩阵

采用行优先存储 ,则矩阵A中任意一个元素aij的存储地址为:(i<=j)

*address(aij)=address(a00)+【(n+(n-1)+(n-2)+…+(n-(i-1)))+j-1】L

即address(aij)= address(a00)+【i*n- (i-1) * i/2+j-i】*L

4.4.3带状矩阵的压缩存储

4.5稀疏矩阵

如果一个矩阵中很多元素的值为零,即零元素的个数远远大于非零元素的个数时,称该矩阵为稀疏矩阵。

根据存储时的附加信息不同,稀疏矩阵的顺序存储方法包括:三元组表示法、带辅助行向量的二元组表示法和伪地址表示法,其中三元组表示法最常用。

在这里插入图片描述

​ 矩阵B的第一行体现了稀疏矩阵A的行数、列数及所含非零元素的总个数。接下来的每一行均代表A中一个非零元素的三元组表示。

猜你喜欢

转载自blog.csdn.net/weixin_48931875/article/details/112406099