模式匹配(第一篇

来源:互联网 发布:阿里数据包导入淘宝 编辑:程序博客网 时间:2024/05/16 17:52

  模式匹配的定义:
  设有主串s和子串t,子串t定位是指在主串s中找到一个与子串t相等的子串。通常把主串s称为目标串,把子串t称为模式串,因此定位也称为模式匹配。匹配成功,是指在目标串s中有一个子串等于模式串t;匹配失败,是指目标串s不存在子串等于模式串t
  关于模式匹配,常见的算法有Brute-Force(BF)算法、KMP算法。
  BF算法的思想是:从目标串s="s0s1sn1"的第一个字符开始和模式串t="t0t1tm1"中的第一个字符比较,若相等,则继续逐个比较后继字符;否则从目标串s的第二个字符开始重新与模式串t的第一个字符比较。依次类推,若存在模式串中的每个字符依次和目标串中的一个连续字符序列相等,则匹配成功,函数返回模式串t中第一个字符在主串s中的位置;否则匹配失败,函数返回-1。算法如下:  

//Brute-Force算法int index(SqString s,SqString t){    int i=0,j,k;    while (i<s.length)    {        for(j=i,k=0;j<s.length && k<t.length &&            s.data[j]==t.data[k]; j++,k++);        if(k==t.length)  //模式串比较完毕            return i;        i++;    }    return -1;}

  上述算法中,当st的当前比较字符相等时,用j扫描s,k扫描t, 依次比较下去,当t的所有字符比较完毕,则说明ts的子串。
  现只用i扫描s,j说明t, 当st的当前比较字符相等时,依次比较下去,即i++,j++; 当st的当前比较字符不相等时进行回溯,即i=ij+1,从头开始比较,即j=0。修改后的算法如下:
  

int index1(SqString s,SqString t){    int i=0,j=0,k;    while (i<s.length && j<t.length)    {        if(s.data[i]==t.data[j]){            i++;  //主串和模式串依次匹配下一个字符            j++;        }        else{       //若主串与模式串当前的字符不相等            i=i-j+1;  //则主串从下一个位置开始匹配            j=0;      //模式串从头开始匹配        }    }    if(j>=t.length)        k=i-t.length;  //返回匹配的第一个字符的下标    else        k=-1;    //模式匹配不成功    return k;}

 完整代码如下:   

//ShunStringBase.h#include <stdio.h>#define  MaxSize 100typedef struct{    char data[MaxSize];    int length;}SqString;//创建串void StrAssign(SqString &str,char cstr[]){    int i;    for(i=0;cstr[i]!='\0';i++)        str.data[i]=cstr[i];    str.length=i;}//串复制void StrCopy(SqString &s,SqString t){    int i;    for(i=0;i<t.length;i++)        s.data[i]=t.data[i];    s.length=t.length;}//判断串s与串t是否相同int StrEqual(SqString s,SqString t){    int same=1,i;    if(s.length!=t.length)        same=0;    else{        for(i=0;i<s.length;i++)            if(s.data[i]!=t.data[i])                same=0;    }    return same;}//求串长int StrLength(SqString s){    return s.length;}//两串比较SqString Concat(SqString s,SqString t){    SqString str;    int i;    str.length=s.length+t.length;    for(i=0;i<s.length;i++)        str.data[i]=s.data[i];    for(i=0;i<t.length;i++)        str.data[s.length+i]=t.data[i];    return str;}//求串s中第i(1≤i≤n)个位置长度为j的子串   SqString SubStr(SqString s,int i,int j){    SqString str;    int k;    str.length=0;    if (i<=0 || i>s.length || j<0 ||        i+j-1 >s.length)    {        printf("参数不正确\n");        return str;    }    for(k=i-1;k<i+j-1;k++)        str.data[k-i+1]=s.data[k];    str.length=j;    return str;}//在串s的第i个位置插入串s2SqString InsStr(SqString s1,int i,SqString s2){    int j;    SqString str;    str.length=0;    if(i<=0 || i>s1.length+1)  //参数不正确时,返回空串    {        printf("参数不正确\n");        return s1;    }    for(j=0;j<i-1;j++)     //将s1.data[0]~s1.data[i-2]复制到str        str.data[j]=s1.data[j];    for (j=0;j<s2.length;j++)  //将s2.data[0]~s2.data[s2.length-1]复制到str        str.data[i+j-1]=s2.data[j];    for(j=i-1;j<s1.length;j++)  //将s1.data[i-1]~s.data[s1.length-1]复制到str        str.data[s2.length+j]=s1.data[j];    str.length=s1.length+s2.length;    return str;}//删除串s中第i个位置长度为j的子串SqString DelStr(SqString s,int i,int j){    int k;    SqString str;    str.length=0;    if (i<=0 || i>s.length || i+j>s.length+1)    {        printf("参数不正确\n");        return str;    }    for(k=0;k<i-1;k++)        str.data[k]=s.data[k];    for (k=i+j-1;k<s.length;k++)        str.data[k-j]=s.data[k];    str.length=s.length-j;    return str;}//在串s中,用串t替换在第i个位置长度为j的子串SqString RepStr(SqString s,int i,int j,SqString t){    int k;    SqString str;    str.length=0;    if (i<=0 || i>s.length || i+j-1 >s.length)    {        printf("参数不正确\n");        return str;    }    for(k=0;k<i-1;k++)        str.data[k]=s.data[k];    for (k=0;k<t.length;k++)        str.data[i+k-1]=t.data[k];    for(k=i+j-1;k<s.length;k++)        str.data[t.length+k-j]=s.data[k];    str.length=s.length-j+t.length;    return str;}//输出串strvoid DispStr(SqString str){    int i;    if (str.length>0)    {        for(i=0;i<str.length;i++)            printf("%c",str.data[i]);        printf("\n");    }}//主函数.cpp#include "ShunStringBase.h"#include <stdio.h>//Brute-Force算法int index(SqString s,SqString t){    int i=0,j,k;    while (i<s.length)    {        for(j=i,k=0;j<s.length && k<t.length &&            s.data[j]==t.data[k]; j++,k++);        if(k==t.length)  //模式串比较完毕            return i;        i++;    }    return -1;}int index1(SqString s,SqString t){    int i=0,j=0,k;    while (i<s.length && j<t.length)    {        if(s.data[i]==t.data[j]){            i++;  //主串和模式串依次匹配下一个字符            j++;        }        else{       //若主串与模式串当前的字符不相等            i=i-j+1;  //则主串从下一个位置开始匹配            j=0;      //模式串从头开始匹配        }    }    if(j>=t.length)        k=i-t.length;  //返回匹配的第一个字符的下标    else        k=-1;    //模式匹配不成功    return k;}void main(){    SqString str,str2;    char s[20]="Helloworld";    char s2[10]="llowo";    StrAssign(str,s);    StrAssign(str2,s2);    //DispStr(str);    printf("主串为: %s\n",s);    printf("模式串为:%s\n",s2);    int n=-2;    n=index(str,str2);    if (n!=-1)    {        printf("匹配成功!\n");    }    else{        printf("匹配失败!\n");    }}

  上述算法的时间复杂度为O(n×m), 其中nm分别为串st的长度。
效果如下:

这里写图片描述

  
模式匹配(第二篇KMP算法
http://blog.csdn.net/sanqima/article/details/48897659  

0 0
原创粉丝点击