朴素模式匹配算法
算法:
- 当主串中与模式串长度相同的子串搞出来,挨个与模式串对比(即子串的第一个字符在主串中的位置为 k , 而i,j 用来移动对比 )
- 当子串与模式串某个对应字符不匹配时,就立即放弃当前子串, 转而检索下一个子串(即k++; i=k; j=1;)
详情见如下代码中的 Index函数
模式串:想尝试在主串中找到相同的串,但未必在主串中存在
子串:一定是在主串中存在的才叫子串
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//串的顺序存储 从数组下标为1开始存储字符
#define MAXLEN 255//预定义最大串长为255
typedef struct{
char ch[MAXLEN];//每个分量存储一个字符
int length;//串的实际长度
}SString;
//朴素模式匹配算法
/*
算法:
当主串中与模式串长度相同的子串搞出来,挨个与模式串对比,
当子串与模式串某个对应字符不匹配时,就立即放弃当前子串
转而检索下一个子串
*/
//不依赖于其他串操作的暴力匹配算法,最坏时间复杂度为O(mn)
int Index(SString S,SString T){
int k=1;//k是从主串中取出的与模式串长度相等的子串 在 主串中的起始位置
int i=k,j=1;//分别用i,j指向模式串和子串的对应位置
while(i<=S.length && j<=T.length){
if(S.ch[i]==T.ch[j]){
++i;
++j;//继续比较后继字符
}
else{
k++;//检查下一个子串
i=k;//把i,j分别指向模式串和子串的第一个字符
j=1;
}
}
if(j>T.length){
//j是否超出T的边界来判断是否T的串是否判断完毕
return k;
}
return 0;//匹配失败
}
//基本操作的实现
//求串长
int StrLength(SString S){
return S.length;
}
//判空操作,若S为空串,则返回TRUE,否则返回FALSE
bool StrEmpty(SString S){
return (S.length==0);
}
//赋值操作,把串T赋值为chars
bool StrAssign(SString &T,SString chars){
for(int i=1;i<=chars.length;i++){
T.ch[i]=chars.ch[i];
}
T.length=chars.length;
return true;
}
//复制操作,由串S复制得到串T
bool StrCopy(SString &T,SString S){
for(int i=1;i<=S.length;i++){
T.ch[i]=S.ch[i];
}
if(T.length<S.length){
T.length=S.length;
}
return true;
}
//求子串,用Sub返回串S的第pos个字符起长度为len的字符
bool SubString(SString &Sub,SString S,int pos,int len){
//子串范围越界
if(pos + len+1>S.length){
printf("子串范围越界\n");
return false;
}
for(int i=pos;i<pos+len;i++){
Sub.ch[i-pos+1]=S.ch[i];//从下标1开始存字符串
}
Sub.length=len;
return true;
}
//比较操作,若S>T, 则返回值>0;若S=T,则返回值=0;若S<T,则<0
int StrCompare(SString S,SString T){
for(int i=1;i<=S.length&&i<=T.length;i++)
if(S.ch[i]!=T.ch[i]){
return (S.ch[i] - T.ch[i]);
}
//扫描过的所有字符都相同,则谁长谁更大,或者等长
return S.length-T.length;
}
//串连接。用T返回由S1,S2连接而成的新串
bool Concat(SString &T,SString S1,SString S2){
for(int i=0;i<=S1.length;i++){
T.ch[i]=S1.ch[i];
}
for(int i=(S1.length+1);i<=S1.length+S2.length;i++){
T.ch[i]=S2.ch[i-S1.length];
}
T.length=S1.length+S2.length;
return true;
}
//
//清空操作,将S清为空串
bool ClearString(SString &S){
S.length=0;
}
//销毁串,将串S销毁
void DestroyString(SString&S){
S.length=0;//静态数组,系统自动回收
}
void PrintString(SString S){
printf("\nString is:");
for(int i=1;i<=S.length;i++){
printf("%c",S.ch[i]);
}
printf("\n");
}
int main(){
SString S1,S2;
char str1[40]="hello?How are you world";
for(int i=0;i<strlen(str1);i++){
S1.ch[i+1]=str1[i];
}
S1.length=strlen(str1);
char str2[40]="How are you";
for(int i=0;i<strlen(str2);i++){
S2.ch[i+1]=str2[i];
}
S2.length=strlen(str2);
int x=Index(S1,S2);
PrintString(S1);
PrintString(S2);
printf("\nindex is %d\n",x);
return 0;
}