串(string):零个或多个任意字符组成的有限序列
s:"a1a2a3……an"
串名 串值 串长
子串:一个串中任意个连续字符组成的子序列
主串:包含子串的串
字符位置:字符在序列中的序号为该字符在串中的位置
子串位置:子串第一个字符在主串中的位置
空格串:由一个或多个空格组成的串
空串:不包含任何字符
串相等:当且仅当两个串的长度相等并且各个对应位置上的字符都相同时,才是相等的
所有的空串是相等的
基本操作:
StrAssign(&T, chars)//串赋值
StrCompare(S, T)//串比较
StrLength(S)//求串长
Concat(&T, s1, s2)//串连结
SubString(&Sub, S, pos, len)//求子串
StrCopy(&T, s)//串拷贝
StrEmpty(S)//串判空
ClearStr(S)//清空串
Index(S, T, pos)//子串的位置
Replace(&S, t, v)//串替换
StrInsert(&S, pos, T)//子串插入
StrDelete(&S,pos,len)//子串删除
DestroyStr(&S)//串销毁
串的顺序存储结构
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 255
typedef int status;
typedef struct {
char ch[MAXSIZE + 1];
int length;
}SString;
#define CHUNKSIZE 80
typedef struct Chunk {
char ch[CHUNKSIZE];
struct Chunk* next;
}Chunk;
typedef struct {
Chunk* head, * tail;
int curlen;
}LString;
链式存储
#define CHUNKSIZE 80
typedef struct Chunk {
char ch[CHUNKSIZE];
struct Chunk* next;
}Chunk;
typedef struct {
Chunk* head, * tail;
int curlen;
}LString;
串的模式匹配算法
确定主串中所含子串(模式串)第一次出现的位置(定位)
算法种类:BF算法,KMP算法
BF:Brute-Force暴力算法,亦称简单匹配算法。采用穷举法的思路。
主串s:aaaabcd
子串t:abc
s的每一个字符开始依次比较
s长度n=6,t长度m=4
Index(S,T,pos);
将主串的第pos个字符和模式串的第一个字符比较
int Index_BF(SString S, SString T ,int pos) {
int i = pos;
int j = 1;
while (i<=S.length&&j<=T.length)
{
if (S.ch[i]==T.ch[j])//主串和子串依次匹配下一个字符
{
++i;
++j;
}
else//主串、子串指针回溯重新开始下一次匹配
{
i = (i - j+1)+1 ;
j = 1;
}
}
if (j>=T.length)
{
return i - T.length;
}
else
{
return 0;
}
}
最好情况:O(m)
最差情况:O(n*m)
平均:O(n*m)
平均效率较差
改进为KMP后提高到O(n+m)
KMP算法:
int next[100] = { 0 };
void get_next(SString T, int next[]) {
int i = 1;
next[1] = 0;
int j = 0;
while (i<T.length)
{
if (j==0||T.ch[i]==T.ch[j])
{
++i; ++j;
next[i] = j;
}
else
{
j = next[j];
}
}
}
int Index_KMP(SString S, SString T, int pos) {
int i = pos;
int j = 1;
while (i <= S.length && j <= T.length)
{
if (j==0||S.ch[i] == T.ch[j])//主串和子串依次匹配下一个字符
{
++i;
++j;
}
else//主串、子串指针回溯重新开始下一次匹配
{
j = next[j];//i不变,j后退
}
}
if (j >= T.length)
{
return i - T.length;
}
else
{
return 0;
}
}
求nextval数组:
int nextval[100] = { 0 };
void get_nextval(SString T, int nextval[]) {
int i = 1;
nextval[1] = 0;
int j = 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];
}
}
}