字符串或串(String)是由数字、字母、下划线组成的一串字符。一般记为 s=“a1a2···an”(n>=0)。它是编程语言中中表示文本的数据类型。
字符串在存储上类似字符数组,它每一位单个元素都是能提取的,字符串的零位是它的长度,如s[0]=10,这提供给我们很多方便,例如高精度运算时每一位都能转化为数字存入数组。
- 空格串:由一个或多个空格组成的串
串的顺序存储表示:
const int Max_length = 100;//最长串长
class string
{
private:
char String[Max_length];//定义最大串长
int size;//数据数量
};
串的堆分配方式:
class string
{
private:
char* ch;
int size;//串长度
public:
string()//默认初始化为空
{
ch = nullptr;
size = 0;
}
};
以下主要分析在堆分配下的功能:
串的复制:
void string::copy_string(char* p)//复制串
{
if (!ch)delete ch;//非空,清除数据
int i = 0;
for (; p[i]; ++i);//获取p的长度
ch = new char[i];
for (size=0
; size < i;size++)
{
ch[size] = p[size];//复制内容
}
}
串的长度
int string::length()//串的长度
{
return size;
}
获取子串位置:
(暴力求解)
int string::SubString(string p)
{
int i = 0, j = 0;
while (ch[i] != '\0' && p[j] != '\0')
{
if (ch[i] == p[j])
{
i++;
j++;
}
else
{
i = i - j + 1;
j = 0;
}
}
if (p[j] == '\0') return (i - j); //主串中存在该模式返回下标号
else return -1; //主串中不存在该模式
}
KMP(求子串位置)
KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息
可以观看以下视频:(比较清晰)
【搬运】油管阿三哥讲KMP查找算法,中英文字幕,人工翻译,简单易懂_哔哩哔哩_bilibili
以下内容根据上面的进行总结:
重点是:求最长的前后缀
next数组的求法:
int* build_Next(char* p)//构建next表
{
int m = strlen(p);//获取字符串长度
int j = 0;
int* next = new int[m];//构建next表
int t = next[0] = -1;//模式串指针
while (j < m - 1)
{
if (0 > t || p[j] == p[t])//匹配
{
j++; t++;
next[j] =t;
//next[j] =(p[j]!=p[t]?t:next[t]);
}
else
{
t = next[t];
}
return next;
}
}
kmp算法:
int kmp(char* p, char* t)//KMP算法
{
int* next = build_Next(t);//构建next表
int n = strlen(p), i = 0;//文本串指针
int m = strlen(t), j = 0;//模式串指针
while (i < n && j < m)
{
if (j==-1 || p[i] == t[j])//匹配的话
{
i++; j++;
}
else
{
j = next[j];//模式串右移
}
}
delete[]next;
if (j == m)
{
return i - j;
}
return -1;
}