Files
Harmon ec0bab599b ok
2022-05-11 19:11:24 +08:00

136 lines
2.6 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <iostream>
using namespace std;
#define MAXSIZE 100
//定义串的结构
typedef struct
{
char ch[MAXSIZE];
int length = 0;
} String;
//为字符串赋值
void InitString(String &s, char *chars)
{
int i = 0, k = 1;
while (chars[i] != '\0')
{
s.ch[k++] = chars[i++];
s.length++;
}
}
//打印字符串
void Print(String s)
{
for (int i = 0; i < s.length; i++)
{
cout << s.ch[i + 1];
}
cout << endl;
}
//获得模式串的next数组
void GetNext(String T, int next[])
{
int j = 1, k = 0;
next[1] = 0; //初始化第一个位置
while (j < T.length)
{
//如果pj==pk或者匹配失败
if (k == 0 || T.ch[j] == T.ch[k])
{
j++;
k++;
next[j] = k; // p[j+1]=p[j]+1
}
else
{
k = next[k]; //匹配失败,滑动窗口
}
}
}
//字符串朴素匹配算法
int KMPMatch(String &S, String &T, int next[])
{
int i = 1, j = 1; //定义初始字符串指针
while (i <= S.length && j <= T.length)
{
//如果匹配成功,或者第一个字符匹配失败,将二者指针后移
if (j == 0 || S.ch[i] == T.ch[j])
{
i++;
j++;
}
else
{
j = next[j]; //匹配失败,移动模板串指针为最大公共前后缀的后一位
}
}
//如果j的值大于当前模式串的长度说明全部匹配成功
if (j > T.length)
{
return i - T.length;
}
return -1;
}
//打印next数组值
void PrintArray(int next[], int n)
{
for (int i = 1; i <= n; i++)
{
cout << next[i] << '\t';
}
cout << endl;
}
//统计模式串在主串中多少个完全匹配的子串
int CountSub(String S, String T, int next[], int n, int m)
{
int count = 0;
int i = 1, j = 1;
while (i <= (n - m + 1))
{
while (i <= S.length && j <= T.length)
{
//如果匹配成功,或者第一个字符匹配失败,将二者指针后移
if (j == 0 || S.ch[i] == T.ch[j])
{
i++;
j++;
}
else
{
j = next[j]; //匹配失败,移动模板串指针为最大公共前后缀的后一位
}
}
//如果j的值大于当前模式串的长度说明全部匹配成功
if (j > T.length)
{
count++;
i = i - T.length + 1;
j = 1;
}
else
{
return count;
}
}
return count;
}
int main()
{
String S, T;
int n = 14;
int next[n + 1];
char s[] = "ababaabaababab";
char t[] = "ab";
InitString(S, s);
InitString(T, t);
GetNext(T, next);
cout << CountSub(S, T, next, n, 2);
}