字符串匹配——BF算法,RK算法(暴力求解)(C/C++)
字符串匹配
问题描述:在主串S中寻找模式串T第一次出现的位置,并返回这个位置。
字符串匹配的暴力搜索方法——BF算法
使用最简单的方法,将模式串与主串进行逐位的比较。
每次偏移量固定设为1,偏移发生在每次失配之后。
代码描述如下:
#include <iostream>
#include <cstring>
using namespace std;
// 使用BF暴力搜索
// 逐字符比较主串S中第一个出现的子串T,返回T出现的第一个位置
// 找不到返回-1
int BFstring(char *S, char *T){
int lenS = strlen(S); // 每个串的长度都需要用到
int lenT = strlen(T);
int i,j;
for(i=0;i<lenS;++i){
for(j=0;j<lenT;j++){ // 逐字符比较
if(S[i+j]!=T[j]) // 出现不匹配
break; // 退出这一轮比较,模式串右移一位
}
if(j==lenT) // 当不匹配退出时,j不等于模式串长度!
return i;
}
return -1; // 退出循环没有返回位置,意味着没有找到返回-1
}
字符串匹配的另一种暴力算法——RK算法
使用哈希函数,使得可以快速判断当前模式串与主串的待匹配子串是否有可能相等。
哈希函数描述:对模式串或子串(主串的待匹配串)逐字符求和,然后取模使其产生哈希冲突的概率降低。
如若为01串,则直接求和即可。
如若为数字串,则求和取模,模数按数字的范围和串长定,一般模26即可。
如若为字符串,则先将字符转换为数字(ASCII码?),然后求和取模,模数一般设置为26即可。
代码描述如下:
#include <iostream>
#include <cstring>
using namespace std;
int BKstring(char *S, char *T){
int lenS = strlen(S);
int lenT = strlen(T);
int hashS(0),hashT(0),i,j;
// 初始化哈希值
for(int k=0;k<lenT;k++){
hashS += (S[k] - 'a'); // 假设为串为全小写字母的串
hashT += (T[k] - 'a');
hashS %= 26;
hashT %= 26;
}
// printf("hashT: %d\nhashS: ",hashT);
// 比对
for(i=0;i<=lenS-lenT;++i){
// printf("%d, ",hashS);
if(hashS == hashT){
int flag=1;
for(int k=0;k<lenT;k++){
if(S[i+k]!=T[k]){
flag = 0;
break;
}
}
if(flag)
return i;
}
// 不匹配更新hashS
hashS -= (S[i] - 'a');
hashS += (S[i+lenT] - 'a');
hashS %= 26;
}
// putchar('\n');
return -1;
}