一、串的表示
1.定长顺序存储
如下:
#define MAXSIZE 255
typedef unsigned char SString[MAXSIZE + 1]
2.堆分配存储
如下:采用malloc得free操作内存
typedef struct
{
? ? char *ch;
? ? int length;
}HString;
3.块链存储表示
//CHUNKSIZE为结点大小,可以配置?
#define CHUNKSIZE 80
typedef struct Chunk
{
? ? char ch[CHUNKSIZE];
? ? struct Chunk *next;
}Chunk;
typedef struct
{
? ? Chunk *head,*tail; /* 串的头和尾指针 */
? ? int curlen; /* 串的当前长度 */
}LString;
二、串的常见基本操作
//串S复制得串T
StrCopy(&T, S)
//串S是否存在
StrEmpty(S)
//S和T比较
StrCompare(S,T)
//串S的长度
StrLength(S)
//清空S串
ClearString(&S)
//字符串连接
Concat(&T,S1,S2)
//返回子串
SubString(&Sub,S,pos,len)
//返回T在S中的位置
Index(S,T,pos)
//用V替换主串S中出现的与T相同的子串
Replace(&S,T,V)
//在串S的pos位置插入T
StrInsert(&S,pos,T)
//删除S串从pos位置起的len长度的串
StrDelete(&S,pos,len)
//串S销毁
DestoryString(&S)
三、串的模式匹配算法
1.子串位置的定位函数
常规的字符匹配算法较简单,此处不举例说明。
2.KMP算法
#include <iostream>
#include <string>
#include <vector>
using namespace std;
//部分匹配表
void cal_next(string &str, vector<int> &next)
{
const int len = str.size();
next[0] = -1;
int k = -1;
int j = 0;
while (j < len - 1)
{
if (k == -1 || str[j] == str[k])
{
++k;
++j;
next[j] = k;//表示第j个字符有k个匹配(“最大长度值” 整体向右移动一位,然后初始值赋为-1)
}
else
k = next[k];//往前回溯
}
}
vector<int> KMP(string &str1, string &str2, vector<int> &next)
{
vector<int> vec;
cal_next(str2, next);
int i = 0;//i是str1的下标
int j = 0;//j是str2的下标
int str1_size = str1.size();
int str2_size = str2.size();
while (i < str1_size && j < str2_size)
{
//如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),
//都令i++,j++. 注意:这里判断顺序不能调换!
if (j == -1 || str1[i] == str2[j])
{
++i;
++j;
}
else
j = next[j];//当前字符匹配失败,直接从str[j]开始比较,i的位置不变
if (j == str2_size)//匹配成功
{
vec.push_back(i - j);//记录下完全匹配最开始的位置
j = -1;//重置
}
}
return vec;
}
int main(int argc, char const *argv[])
{
vector<int> vec(20, 0);
vector<int> vec_test;
string str1 = "bacbababadababacambabacaddababacasdsd";
string str2 = "ababaca";
vec_test = KMP(str1, str2, vec);
for (const auto v : vec_test)
cout << v << endl;
return 0;
}