mirror of
https://github.com/Didnelpsun/CS408.git
synced 2026-02-04 19:34:19 +08:00
104 lines
2.7 KiB
C
104 lines
2.7 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "head.h"
|
|
|
|
// 静态顺序串
|
|
typedef struct {
|
|
char data[MAXSIZE];
|
|
// 串长
|
|
int length;
|
|
} StaticSequenceString;
|
|
|
|
// 动态顺序串
|
|
typedef struct {
|
|
char* data;
|
|
int length;
|
|
} DynamicSequenceString;
|
|
|
|
// 求静态顺序子串
|
|
int SubStaticSequenceString(StaticSequenceString string, StaticSequenceString *substring, int index, int length) {
|
|
// 如果子串越界
|
|
if (index + length > string.length) {
|
|
printf("StaticSequenceString:子串范围越界!");
|
|
return 1;
|
|
}
|
|
for (int i = 0; i < length; i++) {
|
|
substring->data[i] = string.data[index + i];
|
|
}
|
|
substring->length = length;
|
|
return 0;
|
|
}
|
|
|
|
// 对比静态顺序字符串
|
|
int CompareStaticSequenceString(StaticSequenceString string1, StaticSequenceString string2) {
|
|
for (int i = 0; i <= string1.length && i <= string2.length; i++) {
|
|
if (string1.data[i] != string2.data[i]) {
|
|
return string1.data[i] - string2.data[i];
|
|
}
|
|
}
|
|
// 如果扫描过的所有字符都相同,则长度长的字符串更长
|
|
return string1.length - string2.length;
|
|
}
|
|
|
|
// 在静态顺序字符串中定位子串
|
|
// 如果主串中存在与子串相同的子串,则返回在主串中第一次出现的位置,否则返回-1
|
|
int LocateStaticSequenceString(StaticSequenceString mainstring, StaticSequenceString substring) {
|
|
int i = 0;
|
|
// 用于暂存子串
|
|
StaticSequenceString temp;
|
|
while (i < mainstring.length - substring.length + 1) {
|
|
// 从主串切割下来与子串相同长度的子串
|
|
SubStaticSequenceString(mainstring, &temp, i, substring.length);
|
|
// 如果切割下来的子串与子串不相等就后移一位再切割子串
|
|
if (CompareStaticSequenceString(substring, temp) != 0) {
|
|
i++;
|
|
}
|
|
// 否则返回当前的索引
|
|
else {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
// 求模式串的next数组
|
|
// 数组0号索引不存值
|
|
int GetNext(StaticSequenceString string, int *next[]) {
|
|
int i = 1, j = 0;
|
|
next[i] = 0;
|
|
while (i < string.length) {
|
|
if (j == 0 || string.data[i] == string.data[j]) {
|
|
++i, ++j;
|
|
*next[i] = j;
|
|
}
|
|
else {
|
|
if (next[j]) {
|
|
// 模式串回溯
|
|
j = *next[j];
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// KMP算法
|
|
int KMP(StaticSequenceString string1, StaticSequenceString string2) {
|
|
int i = 1, j = 1;
|
|
int length = string2.length + 1;
|
|
int* next = (int*)malloc(length*sizeof(int));
|
|
GetNext(string2, &next);
|
|
while (i <= string1.length && j <= string2.length) {
|
|
if (j == 0 || string1.data[i] == string2.data[j]) {
|
|
i++, j++;
|
|
}
|
|
else {
|
|
// 模式字符串后移
|
|
j = next[i];
|
|
}
|
|
}
|
|
if (j > string2.length) {
|
|
return i - string2.length;
|
|
}
|
|
return -1;
|
|
free(next);
|
|
} |