概述
对一个串中某子串的定位操作称为串的模式匹配,其中待定位的子串称为模式串。算法的基本思想:从主串的第一个位置起和模式串的第一个字符开始比较,如果相等,则继续逐一比较后续字符:否则从主串的第二个字符开始,再重新用上一步的方法与模式串中的字符做比较,以此类推,直到比较完模式串中的所有字符。若匹配成功,则返回模式串在主串中的位置:若匹配不成功,则返回一个可区别于主串所有位置的标记,如“0”。
分析
代码
核心代码:
/* 简单模式匹配 */
/* str指的是总字符串;substr指的是要取匹配的子串 */
int index(Str str,Str substr) {
int i=0,j=0;// 串从数组下标0位置开始存储,因此初值为0;i表示的主串中的下标起始位置;j表示的模式串中的下标起始位置
while(i<str.length&&j<substr.length) {
if(str.ch[i]==substr.ch[j]) { // 如果当前位置的字符匹配
i++;
j++;// 则匹配下一对字符
} else { // 如果不能配对
i=i-j+1;// i则从主串的下一位置开始,k中记录了上一次的起始位置
j=0;// 将j重置为0
}
}
if(j==substr.length) {// 如果匹配成功,由于j++和下标从0开始,最后j的值会变成模式串的长度 (注:以main函数中的例子来说,此时j=5)
return i-j;// 此时起始位置即为i-j(注:以main函数中的例子来说,此时i=10,j=5,而i-j=10-5即为模式串在主串中的位置)
} else {
return 0;
}
}
完整代码:
#include<stdio.h>
#include<stdlib.h>
#define maxSize 20
typedef struct {
char *ch;
int length;
} Str;
/* 打印字符串 */
void printStr(Str str) {
printf("\n");
for(int i=0; i<str.length; i++) {
printf("%c",str.ch[i]);
}
printf("\n");
}
/* 简单模式匹配 */
/* str指的是总字符串;substr指的是要取匹配的子串 */
int index(Str str,Str substr) {
int i=0,j=0;// 串从数组下标0位置开始存储,因此初值为0;i表示的主串中的下标起始位置;j表示的模式串中的下标起始位置
while(i<str.length&&j<substr.length) {
if(str.ch[i]==substr.ch[j]) { // 如果当前位置的字符匹配
i++;
j++;// 则匹配下一对字符
} else { // 如果不能配对
i=i-j+1;// i则从主串的下一位置开始,k中记录了上一次的起始位置
j=0;// 将j重置为0
}
}
if(j==substr.length) {// 如果匹配成功,由于j++和下标从0开始,最后j的值会变成模式串的长度 (注:以main函数中的例子来说,此时j=5)
return i-j;// 此时起始位置即为i-j(注:以main函数中的例子来说,此时i=10,j=5,而i-j=10-5即为模式串在主串中的位置)
} else {
return 0;
}
}
int main() {
Str str,substr;
str.ch="ABABCABCACBAB";
str.length=13;
substr.ch="ABCAC";
substr.length=5;
int i=index(str,substr);
printf("%d\n",i);
return 0;
}
运行结果: