#include"stdio.h"
#include"stdlib.h"
#include"iostream"
#include"string.h";
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef struct
{
char* ch;
int length;
}HString;
int InitHSting(HString& H)
{
H.ch = (char*)malloc(sizeof(char));
H.ch = NULL;
H.length = 0;
return OK;
}//初始化
int CreateString(HString& H, char* chars)
{
InitHSting(H);
int i;
if (H.ch)free(H.ch);
i = strlen(chars);
if (!i)
{
H.ch = NULL;
H.length = 0;
}
else {
if (!(H.ch = (char*)malloc(i * sizeof(char)))) return ERROR;
}
for (int j = 0; j < i; j++)
{
H.ch[j + 1] = chars[j];
}
H.length = i;
return OK;
}
int DisplayString(HString& H)
{
for (int i = 1; i < H.length; i++)
{
printf("%4c", H.ch[i]);
}
printf("\n");
return OK;
}
int index_BF(HString S, HString T, int pos)
{
int i, j;
i = pos; j = 1;
while (i <= S.length && j <= T.length)
{
if (S.ch[i] == T.ch[j]) { ++i, ++j; }
else { i = i - j + 2, j = 1; }
}
if (j > T.length) { printf("BF算法匹配结果:%d\n", (i - T.length)); }
else { printf("匹配失败\n"); }
return OK;
}
void get_next(HString T, int next[])
{
int i = 1;
int j = 0;
next[1] = 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(HString S, HString T, int pos)
{
int next[255];
get_next(T, next);
int i;
int j = 1;
i = pos;
while (i <= S.length && j <= T.length)
{
if (j == 0 || S.ch[i] == T.ch[j])
{
++i; ++j;
}
else j = next[j];
}
if (j > T.length) printf("KMP算法匹配结果:%d\n", (i - T.length));
else { printf("匹配失败\n"); }
return ERROR;
}
int main()
{
int i;
int next[255];
HString T, S;
char str1[255];
char str2[255];
printf("请输入主串S:");
cin >> str1;
printf("请输入子串T:");
cin >> str2;
CreateString(S, str1);
CreateString(T, str2);
printf("1:使用BF算法匹配\n");
printf("2:打印next数值的值\n");
printf("3:使用KMP算法匹配\n");
printf("4:遍历串\n");
printf("5:结束操作\n");
do {
printf("请输入选择:");
scanf_s("%d", &i);
switch (i)
{
case 1:index_BF(S, T, 1); break;
case 2:get_next(T, next);
for (int m = 1; m < (T.length + 1); m++)
{
printf("%4d", next[m]);
}printf("\n"); break;
case 3:index_KMP(S, T, 1); break;
case 4:DisplayString(S); DisplayString(T);
case 5:printf("操作已结束"); break;
default:printf("该选择不存在,请重新输入\n");
}
} while (i != 5);
}
Java语言
BF算法
public int bruteForce(String text, String pattern) {
int n = text.length();
int m = pattern.length();
for (int i = 0; i <= n - m; i++) {
int j;
for (j = 0; j < m; j++) {
if (text.charAt(i + j) != pattern.charAt(j)) {
break;
}
}
if (j == m) {
return i;
}
}
return -1; // 如果没有找到匹配,返回-1
}
KMP算法
public int KMP(String text, String pattern) {
int[] lsp = computeLSPArray(pattern);
int j = 0; // 记录模式字符串的索引
int i = 0; // 记录文本字符串的索引
int n = text.length();
int m = pattern.length();
while (i < n) {
if (pattern.charAt(j) == text.charAt(i)) {
i++;
j++;
}
if (j == m) {
return i - j;
} else if (i < n && pattern.charAt(j) != text.charAt(i)) {
if (j != 0) {
j = lsp[j - 1];
} else {
i = i + 1;
}
}
}
return -1; // 如果没有找到匹配,返回-1
}
// 计算最长公共前后缀数组(Longest Proper Prefix which is suffix)
public int[] computeLSPArray(String pattern) {
int m = pattern.length();
int[] lsp = new int[m];
int len = 0; // 记录最长公共前后缀的长度
int i = 1;
lsp[0] = 0; // 第一个位置的lsp总是0
while (i < m) {
if (pattern.charAt(i) == pattern.charAt(len)) {
len++;
lsp[i] = len;
i++;
} else {
if (len != 0) {
len = lsp[len - 1];
} else {
lsp[i] = len;
i++;
}
}
}
return lsp;
}
这两个算法都用于在文本字符串中查找模式字符串。BF算法是最简单的字符串匹配算法,它会尝试所有可能的对齐方式,但是它并不高效。KMP算法通过使用一个称为"最长公共前后缀"的辅助数组来避免不必要的比较,从而实现更高的效率。