朴素模式匹配算法

朴素模式匹配算法

算法:

  1. 当主串中与模式串长度相同的子串搞出来,挨个与模式串对比(即子串的第一个字符在主串中的位置为 k , 而i,j 用来移动对比 )
  2. 当子串与模式串某个对应字符不匹配时,就立即放弃当前子串, 转而检索下一个子串(即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;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值