字符串是n个字符组成的有限序列,串中包含的字符个数为串的串的长度
空串:长度为 0 的串,不包含任何字符
空格串:有多个或一个空格组成,长度为空格数
子串:串中任意个连续的字符组成的子序列
主串:包含子串的串
子串的位置:子串的第一个字符在主串中的序号
字符串大小的比较:
ADT String
DataModel
串中的数据元素仅由一个字符组成,相邻元素具有前驱和后继关系
Operation
StrAssign :串赋值
StrLength :求串S的长度
Strcat :串连接
StrSub :求子串
StrCmp :串比较
StrIndex :子串定位
StrInsert :串插入
StrDelete :串删除
endADT
字符串是数据元素为单个字符的线性表,一般采用顺序存储,即用数组来存储串的字符序列
方案 1:用一个变量来表示串的实际长度
方案 2:用数组的 0 号单元存放串的长度,从 1 号单元开始存放串值
方案 3:在串尾存储一个不会在串中出现的特殊字符作为串的终结符,表示串的结尾
在主串S中寻找字串的T的过程称为模式匹配,T称为模式
BF算法
从主串S的第一个在字符开始和模式T的第一个字符进行比较。若相等,则继续比较后续字符,否则,从主串的第二字符开始和模式T的第一个字符开始匹配。
1. 在串 S 和串 T 中设比较的起始下标 i 和 j;
2. 循环直到 S 或 T 的所有字符均比较完
2.1 如果S[i] 等于T[j],继续比较 S 和 T 的下一个字符;
2.2 否则,将 i 和 j 回溯,准备下一趟比较;
3. 如果T中所有字符均比较完,则返回匹配的起始比较下标;否则返回 0;
int BF(char S[ ], char T[ ])
{
int i = 0, j = 0;
while (S[0] != '\0'&&T[0] != '\0')// 遍历字符串
{
if (S[i] == T[j]) {
i++; j++;
}//对应匹配成功则继续往下
else {
i = i – j + 1; j = 0;
} //匹配不成功则回溯
}
if (T[j] == '\0') return (i – j + 1); //至模式到终止符,表示匹配成功
else return 0;
}
BF算法——性能分析
最好情况:不成功的匹配都发生在串 T 的第 1 个字符
最坏情况:不成功的匹配都发生在串 T 的最后一个字符
所以O(n*m)
希望某趟在S[i]和T[j]匹配失败后,下标i不回溯,下标j回溯至某个位置k,使得T[k]对准S[i]继续进行比较。
用next[j]表示T[j]对应的k值
void getNext(string T,int length, int next[])//计算next函数值
{
int j=0,k=-1;
next[0]=-1;
while(j
KMP算法:
1. 在串 S 和串 T 中分别设比较的起始下标 i 和 j;
2. 循环直到 S 或 T 的所有字符均比较完
2.1 如果S[i]等于T[j],继续比较 S 和 T 的下一个字符;
否则,将 j 向右滑动到next[j]位置,即 j=next[j];
2.2 如果 j=-1,则将 i 和 j 分别加 1,准备下一趟比较;
3. 如果 T 中所有字符均比较完毕,则返回匹配的起始下标;否则返回 0;
int KSP(string s, string t) {
int i = 0, j = 0;
while (s[i] != '\0' && t[j] != '\0') {
if (s[i] == t[j]) {
i++;j++
}
else {
j = next[j];//匹配不成功,j回溯
}
if (j == -1) {
i++; j++;//j回溯到最后一个依然不成功,i++
}
}
}
数组:由一组类型相同的数据元素构成的有序集合,每个数据元素称为一个数组元素(简称为元素),每个元素受 n(n≥1)个线性关系的约束,每个元素在 n 个线性关系中的序号i1、i2、…、in 称为该元素的下标,并称该数组为 n 维数组
在数组上一般不能执行删除与插入某个数组元素的操作,数组没有插入和删除操作,所以,不用预留空间,适合采用顺序存储
读操作:给定下标读取相应的数组元素
写操作:给定下标存储或修改相应数组元素
按行优先:先存储行号较小的元素,行号相同者先存储列号较小的元素
按列优先:先存储列号较小的元素,列号相同者先存储行号较小的元素
以按行优先为例:
稀疏矩阵是零元素居多的矩阵
三元组表示非零元素的行号、列号、非零元素值
三元组结构定义:
template
struct element
{
int row, col;
DataType item
};
const int MaxTerm = 100;
struct SparseMatrix
{
element data[MaxTerm];
int mu, nu, tu;
};
将每个非零元素对应的三元组存储为一个链表节点,结点由五个域构成。
data:表示存储非零元素对应三元组
right:表示同一行的下一个三元组结点
down:表示同一列的下一个三元组结点
struct OrthNode
{
Element data;
OrthNode *right, *down;
};
将稀疏矩阵每一行的非零元素按其列号从小到大由right域构成一个行链表,每一列的非零元素按其行号从小到大由down域构成一个列链表。
为了实现对某一行链表的头指针进行快速查找,将这些头指针存储在一个数组HA中,同理,对于列,存储在HB中
void tran(matrix& a, matrix& b) {//a b均为三元组
int pa, pb, col;//数组a角标 数组b角标 col列元素
b.mu = a.nu; b.mu = a.nu; b.tu = a.tu;//行列互换
//mu 三元组a所代表矩阵的总行数 nu 三元组a所代表矩阵的总列数 tu 三元组a所代表矩阵的总非零元素的个数
pb=0;
for (col = 1; col <= a.mu; col++) {//依次遍历三元组a代表矩阵的每一列
for(pa=0;pa
void tran(matrix& a, matrix& b) {//a b均为三元组
int i, j, k;
b.mu = a.nu; b.mu = a.nu; b.tu = a.tu;//行列互换
//mu 三元组a所代表矩阵的总行数 nu 三元组a所代表矩阵的总列数 tu 三元组a所代表矩阵的总非零元素的个数
for(i = 0; i < a.tu; i++) {//依次遍历三元组a代表矩阵的每一列
j = a.data[i].col;//去三元组的列号
num[j]++;//num初始化
}
copt[1] = 0;
for (i = 0; i < a.tu; i++) {
copt[i] = copt[i - 1] = num[i - 1];
}
for(i=0;i
广义表是哪个数据元素的有限序列,每个数据元素可以是不同的,可以是单个数据,也可以是一个集合,通常大写字母表示广义表,小写字母表示单个元素。
广义表中数据元素的个数称为广义表的长度
广义表中括号最大嵌套层数称为广义表的深度
称第一个元素为表头
除去表头其他元素称为表尾
(1)A=()——A是一个空表,其长度为零,深度为1
(2)B=(e)——表B只有一个原子e,B的长度为1,深度为1
(3)C=(a,(b,c,d))——表C的长度为2,两个元素分别为原子a和子表(b,c,d),深度为2
(4)D=(A,B,C)——表D的长度为3,三个元素都是广义表。显然,将子表的值代入后,则有D=(( ),(e),(a,(b,c,d))),深度为3
(5)E=(E)——这是一个递归的表,它的长度为2,E相当于一个无限的广义表E=(a,(a,(a,(a,…)))),深度为无穷。
广义表的逻辑结构图:
广义表的数据元素a用一个节点来表示;若x为单元素,则用矩形结点表示;若x为广义表,则用圆形结点表示;
广义表的特性:
采用链接存储结构来存储广义表。
头尾表示法:若广义表不空,则可分解为表头和表尾,反之,对确定的表头和表尾可以确定一个广义表。
表结点:存储广义表
原子结点:存储单元素
tag:区分表结点域原子结点
hp:指向表头的指针
tp:指向表尾的指针
atom:存放单元素的的数据域
Glist creatGlist(Glist C){
C=(Glist)malloc(sizeof(Glist));
C->tag=1;
C->hp=(Glist)malloc(sizeof(Glist));
C->tp=NULL;
//表头原子a
C->hp->tag=0;
C->atom='a';
C->hp->tp=(Glist)malloc(sizeof(Glist));
C->hp->tp->tag=1;
C->hp->tp->hp=(Glist)malloc(sizeof(Glist));
C->hp->tp->tp=NULL;
//原子b
C->hp->tp->hp->tag=0;
C->hp->tp->hp->atom='b';
C->hp->tp->hp->tp=(Glist)malloc(sizeof(Glist));
//原子c
C->hp->tp->hp->tp->tag=0;
C->hp->tp->hp->tp->atom='c';
C->hp->tp->hp->tp->tp=(Glist)malloc(sizeof(Glist));
//原子d
C->hp->tp->hp->tp->tp->tag=0;
C->hp->tp->hp->tp->tp->atom='d';
C->hp->tp->hp->tp->tp->tp=NULL;
return C;
}