串是由零个或者多个字符组成的有序序列,又名叫字符串。在串中涉及到一下几个概念:串的长度、空串、子串、以及串的比较和串的模式匹配。
串的比较:
计算机中使用的是标准的ASCII编码,是由7位二进制数表示一个字符,总共可表示2^7=128个字符,后来由于特殊符号的出现,扩展成8位二进制数表示一个字符,共表示2^8=256个字符。再后来由于世界上的语种非常的多,就产生了Unicode编码,用16位二进制数表示一个字符,总共可表示2^16=6.5万多个字符。当然,Unicode编码的前256个字符和ASCII码完全相同。而字符串的比较则是逐位按照ASCII码的大小进行比较,那么软件中查取相应单词的过程就是这样产生的。
串的模式匹配:
普通的模式匹配算法:
#include
#include
#include
using namespace std;
int BF(const char *des, const char *src, int pos)//返回下标
{
if (des == nullptr || src == nullptr)
{
return -1;
}
int lend = strlen(des);
int lens = strlen(src);
if (pos < 0 || p >= lend)
{
return -1;
}
//while循环进行查找
int i = pos;
int j = 0;
while (i < lend && j < lens)
{
if (des[i] == src[j])
{
++i;
++j;
}
else
{
i = i-j+1;
j = 0;
}
}
if (j >= lens)
{
return i-j;
}
return -1;
}
int main()
{
return 0;
}
next数组的计算相当的简单,不同的教材上方法可能有些许差异,即:next[0] = 0 或者 next[0] = -1;
例:char arr[] = "a b a b a a a b a";
int next[] = {0, 1, 1, 2, 3, 4, 2, 2, 3};
【nextval数组】
nextval数组是next数组的一个改进版本。需要注意的是当next[0] = 0时,next数组的值是表示的第几个元素,当
next[0] = -1的时候,表示的是当前下标为next数组值得元素。
例: char arr[] = "a b a b a a a b a";
int nextval[] = {0, 1, 0, 1, 0, 4, 2, 1, 0};
KMP算法next版本实现:
#include
#include
#include
#include
#include
using namespace std; void findNext(const char *src, int *next) { //入口检查 if (src == nullptr || next == nullptr) { return ; } int i = 1;//表示当前要求next数组元素的下标 int j = 0;//表示next的数组元素 next[0] = -1; next[1] = 0; int lens = strlen(src); while (i < lens) { //此处的j == 0保证不会出现 j==-1的情况 if (j==0 || src[i] == src[j]) { ++i; ++j; next[i] = j; } else { j = next[j]; } } } int KMP(const char *des, const char *src, int pos) { if (des == nullptr || src == nullptr) { return -1; } int lend = strlen(des); int lens = strlen(src); int i = pos; int j = 0; //动态创建next数组 int *next = new int[100]; findNext(src, next); while (i < lend && j < lens) { if (j==-1 || des[i] == src[j]) { ++i; ++j; } else { j = next[j]; } } delete []next; if (j > lens) { return i-lens; } else { return -1; } } int main() { char *des = "abcdefgoogle"; //char *src = "ef"; //char *src = "le"; //char *src = ""; //char *src = nullptr; char *src = " "; int pos = KMP(des, src, 2); cout<
<
KMP算法nextval版本实现:
#include
#include
#include
#include
void findNextVal(const char *src, int *nextval)
{
if (src == nullptr || nextval == nullptr)
{
return ;
}
int lens = strlen(src);
if (lens == 0)
{
return ;
}
nextval[0] = -1;
nextval[1] = 0;
int i = 1;
int j = 0;
while (i < lens)
{
if (j == 0 || src[i] == src[j])
{
++i;
++j;
if (src[i] != src[j])
{
nextval[i] = j;
}
else
{
nextval[i] = nextval[j];
}
}
else
{
j = nextval[j];
}
}
}
int KMP(const char *des, const char *src, int pos)
{
if (des == nullptr || src == nullptr)
{
return -1;
}
int lend = strlen(des);
int lens = strlen(src);
if (pos < 0 || pos >= lend)
{
return -1;
}
int i = pos;
int j = 0;
int nextval[100];
findNextVal(src, nextval);
while (i < lend && j < lens)
{
if (j == 0 || des[i] == src[j])
{
++i;
++j;
}
else
{
j = nextval[j];
}
}
if (j >= lens)
{
return i-j;
}
else
{
return -1;
}
}
int main()
{
char *des = "abcdefgoogle";
//char *src = "ef";
//char *src = "le";
//char *src = "";
//char *src = nullptr;
char *src = " ";
int pos = KMP(des, src, 2);
cout<
<