#include #include #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); }