串的存储结构
#include <iostream>
#define MAXLEN 255
//串的顺序存储
//静态数组实现(定长顺序存储)
typedef struct {
char ch[MAXLEN];//每个分量存储一个字符
int length;//串得实际长度
}SString;
//动态数组实现(堆分配存储)
typedef struct {
char* ch;//按串长分配存储区,ch指向串的基地址
int length;//串的长度
}HString;
//串的链式存储
typedef struct StringNode {
char ch;//每个结点存1个字符。若存多个字符,可改为"ch[m]",m为常数
struct StringNode* next;
}StringNode,*String;
串的基本操作
//求子串(顺序存储)
bool SubString(SString& Sub, SString S, int pos, int len) {
if (pos + len - 1 > S.length)//子串范围越界
return false;
for (int i = pos; i < pos + len; i++) {
Sub.ch[i - pos + 1] = S.ch[i];
}
Sub.length = len;
return true;
}
//比较两个串(顺序存储)
int StrCompare(SString S, SString T) {
for (int i = 1; i <= S.length && i <= T.length; i++) {
if (S.ch[i] != T.ch[i])
return S.ch[i] - T.ch[i];
}//若S>T,则返回值>0;若S<T,则返回值<0;若S=T,则返回值=0
return S.length - T.length;//扫描的所有字符都相等,则长度更大的串更大
}
//定位操作(顺序存储)。若子串S中存在与串T值相同的子串,则返回它在主串S中第一次出现的位置;否则函数值为0
int Index1(SString S, SString T) {
int i = 1, n = StrLength(S), m = StrLength(T);
SString Sub;//用于暂存子串
while (i <= n - m + 1) {
SubString(Sub, S, i, m);
if (StrCompare(Sub, T) != 0)
++i;
else return i;//返回子串在主串中的位置
}
return 0;//S中不存在与T相等的子串
}
简单的模式匹配算法
//朴素模式匹配
int Index2(SString S, SString T) {
int i = 1, j = 1;
while (i <= S.length && j <= S.length) {
if (S.ch[i] == T.ch[i]) {
++i; ++j;//继续比较后继字符
}
else {
i = i - j + 2;
j = 1;//指针后退重新开始匹配
}
}
if (j > T.length)
return i - T.length;
else
return 0;
}
KMP算法及其优化
//KMP算法
int Index_KMP(SString S, SString T, int next[]) {
int i = 1, j = 1;
while (i <= S.length && j <= S.length) {
if (j==0||S.ch[i] == T.ch[i]) {
++i; ++j;//继续比较后继字符
}
else {
j = next[j];//模式串向后移动
}
}
if (j > T.length)
return i - T.length;//匹配成功
else
return 0;
}
//求next数组
void get_next(SString T, int next[]) {
int i = 1, j = 0;
next[1] = 0;
while (i < T.length) {
if (j == 0 || T.ch[i] == T.ch[j]) {
++i; ++j;
next[i] = j;//若循环继续,则next[j+1]=next[j]+1
}
else {
j = next[j];//否则令j=next[j],循环继续
}
}
}
//求nextval数组
void get_nextval(SString T, int nextval[]) {
int i = 1, j = 0;
nextval[1] = 0;
while (i < T.length) {
if (j == 0 || T.ch[i] == T.ch[j]) {
++i; ++j;
if (T.ch[i] != T.ch[j])
nextval[i] = j;
else
nextval[i] = nextval[j];
}
else {
j = nextval[j];//否则令j=nextval[j],循环继续
}
}
}
//以下形式同为求nextval数组
/* nextval[1]=0;
for(int j=2;j<=T.length;j++){
if(T.ch[next[j]==T.ch[j])
nextval[j]=nextval[next[j]];
else
nextval[j]=next[j];
}*/