数据结构与算法-字符串与多维数组

字符串

  • 串的定义
    字符串(串):零个或多个字符组成的有限序列S=“a1,a2…an”(n>=0)
    S为串名,n为串的长度, “ 为定界符, 字符序列为串值。

  • 串的基本概念
    空串:是指长度=0的串,它不包含任何字符。
    空格串:是仅由一个或多个空格组成的串,长度大于等于1。
    子串:串中任意个连续的字符组成的子序列。
    主串:包含子串的串相应地称为主串。
    位置:字符在序列中的序号。子串在主串中的位置则以子串的第一个字符在主串中的位置来表示。
    相等:两个串的长度相等,并且对应位置的字符都相等。

  • 抽象数据类型定义
    ADT String
    DataModel
    串中的数据元素仅由一个字符组成,相邻元素具有前驱和后继关系
    Operation
    StrAssign:串赋值
    StrLength:求串S的长度
    Strcat:串连接
    StrSub:求子串
    StrCmp:串比较
    StrIndex:子串定位
    StrInsert:串插入
    StrDelete:串删除
    endADT

  • 串的存储
    字符串通常采用顺序存储,即用数组存储(定长顺序串)
    堆串
    块链串

  • 串的基本操作
    C/C++语言提供了很多关于字符串操作的库函数,如strcpy函数、strncpy函数、strlen函数、strcmp函数、strcat函数等。除此之外,C++语言也有STL模板类string来操作字符串。

  • 串的模式匹配

    • BF算法(暴力匹配算法)
int Index(SString S,int pos,SString T){
	int i=pos,j=1;
	while (i<=S.len &&j<=T.len)
		if (S.ch[i]=T.ch[jl)
			{
			++i
			++j
		}
		else{
			i=i-j+2;
			j=1
		}
	if (j>T.len)
		return i-T.len;
	else
		return 0;
}
O(m*n)
    • KMP算法
class Solution {
public:
    int strStr(string s, string p) {
        int n = s.size(), m = p.size();
        if(m == 0) return 0;
        //设置哨兵
        s.insert(s.begin(),' ');
        p.insert(p.begin(),' ');
        vector<int> next(m + 1);
        //预处理next数组
        for(int i = 2, j = 0; i <= m; i++){
            while(j and p[i] != p[j + 1]) j = next[j];
            if(p[i] == p[j + 1]) j++;
            next[i] = j;
        }
        //匹配过程
        for(int i = 1, j = 0; i <= n; i++){
            while(j and s[i] != p[j + 1]) j = next[j];
            if(s[i] == p[j + 1]) j++;
            if(j == m) return i - m;
        }
        return -1;
    }
};
O(m+n)

多维数组

数组的定义

数组:由一组类型相同的数据元素构成的有序集合,每个数据元素称为一个数组元素(简称为元素),每个元素受 n(n≥1)个线性关系的约束,每个元素在 n 个线性关系中的序号i1、i2、…、in 称为该元素的下标,并称该数组为 n 维数组

数组的特点

(1)元素本身可以具有某种结构,属于同一数据类型;
(2)数组是一个具有固定格式和数量的数据集合。

数组的基本操作

(1)存取:给定一组下标,读出对应的数组元素
(2)修改:给定一组下标,存储或修改与其相对应的数组元素

ADT Matrix
DataModel
   相同类型的数据元素的有序集合,每个元素受n(n≥1)个线性关系的约束
Operation
   InitMatrix:数组的初始化
   DestroyMatrix:数组的销毁 
   GetMatrix:读操作,读取这组下标对应的数组元素
   SetMatrix:写操作,存储或修改这组下标对应的数组元素
endADT

数组的存储结构

数组没有插入和删除操作,所以,不用预留空间,适合采用顺序存储

  • 按行优先:先存储行号较小的元素,行号相同者先存储列号较小的元素
    • aij前面的元素个数=整行数×每行元素个数+本行中aij前面的元素个数=(i -l1)×(h2-l2+1)+(j -l2)
  • 按列优先:先存储列号较小的元素,列号相同者先存储行号较小的元素
  • 数组在内存中以一维数组存储
    在这里插入图片描述

特殊矩阵的压缩存储

  • 特殊矩阵:
    矩阵中很多值相同的元素并且它们的分布有一定的规律

  • 特殊矩阵如何压缩存储
    为值相同的元素分配一个存储空间

  • 特殊矩阵压缩存储的要求
    保证随机存取,即在O(1)时间内寻址

  • 对称矩阵的压缩存储
    在这里插入图片描述

    • aij 在一维数组中的序号= i×(i-1)/2+ j
      ∵一维数组下标从 0 开始
      ∴aij 在一维数组中的下标k = i×(i-1)/2+ j-1
    • 对称矩阵压缩存储后的寻址方法
      对于下三角中的元素aij(i ≥ j):k=i×(i-1)/2+j -1
      对于上三角中的元素aij(i<j),因为aij=aji,则 k=j×(j-1)/2+i -1
  • 三角矩阵的压缩存储
    下三角矩阵
    在这里插入图片描述
    下三角矩阵压缩存储后的寻址方法
    对于下三角中的元素aij(i ≥ j):k=i×(i -1)/2 + j-1
    对于上三角中的元素aij(i<j):k=n×(n + 1)/2

  • 对角矩阵的压缩存储
    对角矩阵:所有非零元素都集中在以主对角线为中心的带状区域中,所有其他元素都为零
    在这里插入图片描述
    在这里插入图片描述
    元素 aij 在一维数组中的序号=2 + 3(i-2)+( j-i + 2)=2i + j-2
    ∵一维数组下标从 0 开始
    ∴元素 aij 在一维数组中的下标= 2i + j-3

稀疏矩阵的压缩存储

  • 稀疏矩阵:矩阵中有很多零元素,并且分布没有规律
  • 稀疏矩阵如何压缩存储?
    只存储非零元素,零元素不分配存储空间
  • 如何只存储非零元素?
    三元组:(行号,列号,非零元素值)

三元组

  • 三元组:(行号,列号,非零元素值)
template <typename DataType>
struct element
{
     int row, col;
     DataType item 
};
  • 三元组表:将稀疏矩阵的非零元素对应的三元组所构成的集合,按行优先的顺序排列成一个线性表
    ((1, 1, 3), (1, 4, 7), (2, 3, 1), (3, 1, 2), (5, 4, 8))
  • 三元组顺序表:采用顺序存储结构存储三元组表

在这里插入图片描述

const int MaxTerm = 100;
struct SparseMatrix
{
      element data[MaxTerm];
      int mu, nu, tu; 
};
  • 三元组顺序表不适合什么情况?
    稀疏矩阵的加法、乘法等操作,非零元素的个数及位置都会发生变化,则在三元组顺序表中就要进行插入和删除操作,顺序存储就十分不便
  • 三元组顺序表的矩阵转置
    在这里插入图片描述
    2.快速转置一基本策略
    转置前矩阵

在这里插入图片描述

十字链表

十字链表:采用链接存储结构存储三元组表

在这里插入图片描述
在这里插入图片描述

  • 数据类型定义
typedef struct OLNode
{
int row,col;//行、列号
ElemType value;
struct OLNode*right,*down;//行、列指针
}OLNode,*OLink;

typedef struct
{
OLink*row_head,*col head;/行列链表头指针数组
int m,n;
}CrossList;
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值