简单的就不写了,以下只总结重点内容。
字符串
一、模式匹配
1.定义:给定主串S="s1s2…sn"和T=“t1t2…tm”,在主串S中寻找T的过程称为模式匹配,T称为模式。如果匹配成功,返回T在S中的位置,否则返回0。
2.方法:BF算法和KMP算法。
BF算法
从主串S的第0个字符开始和T的第0个字符进行比较,若相等,继续比较两者后续字符;否则,主串S下一个字符和T第0个字符比较。
若T中的字符全部比较完毕,匹配成功,S的字符全部比较完,匹配失败。
过程如下:
int BF(char S[],char T[])
{
int start=0;
int i=0,j=0;
while((S[i]!='\0')&&(T[j]!='\0'))
{
if(S[i]==T[j])
{
i++;
j++;
}
else
{
start++;
i=start;
j=0;
}
}
if(T[i]=='\0')
return start+1;
else return 0;
}
BF算法匹配不成功时存在大量回溯,时间性能低。
KMP算法
对BF算法改进,主串不进行回溯,T向右滑动到新比较起点k。
k怎么找?举个例子:假设主串当前位置为i,子串为j。
S:a b a b c a b c a c b a b
T:a b a b b
T的最后一个b与S中的c不匹配,此时i=4,j=4,T需要向右滑动到比较的新起点。发现k与T串有关。从T中不匹配的位置向前看,abab,很容易看出把T移动到第二个a的位置下,即:
S:a b a b c a b c a c b a b
T:_ _ a b a b b (努力对齐)
找规律:abab,标个序号(0)(1)(2)(3),发现(0)!=(3)即a!=b,(0)(1)=(2)(3)即ab=ab,(0)(1)(2)!=(1)(2)(3)即aba!=bab,所以有两个元素可以不用重新匹配了,又因为j的下标从0开始,所以k=2,j改成k也就是T的第3个字母与S的i位置的字母比较。
用next[j]表示这个k如下:
void Next_(char t[],int next[])
{
int j=1,k;
next[0]=-1;
while(t[j]!='\0')
{
k=next[j-1];
while(k!=-1&&t[k]!=t[j-1])//这里的循环怎么理解,看下图
k=next[k];
next[j]=++k;
j++;
}
}
void KMP(char *s,char *p,int *next)
{
int i=0,j=0,k;
while(s[i]!='\0'&&t[i]!='\0')
{
if(j==-1||s[i]==t[j])
{
i++;
j++;
}
else j=next[j];
}
if(t[j]=='\0')
return i-j;
else return 0;
}
最后放个例子:
多维数组
一、矩阵的压缩存储
对称矩阵的压缩存储
三角矩阵的压缩存储
对角矩阵的压缩存储
二、稀疏矩阵的压缩存储
三元组顺序表