数据结构(c++) 串的匹配BF->KMP->BM算法

#include<stdio.h> 
#include<stdlib.h>

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -1
#define INFEASIBLE -2

typedef struct 
{
    char *ch;
    int length;
}String;

void String_Assign(String &S,char A[])
{
    int i;
//  if(S.ch)
//      free(S.ch);
    for(i=0;A[i]!='\0';i++);//求字符数组长度
    if(i==0)//字符数组为空
    {
        S.ch=NULL;
        S.length=i;
    }
    else
    {
        S.ch=(char *)malloc(i*sizeof(char));//申请空间并判断是否为空
        if(!S.ch)
            exit(OVERFLOW);
        S.length=i;
        for(i=0;i<S.length;i++)//逐一复制字符
            S.ch[i]=A[i];
    }
}//字符串赋值

void String_Init(String &S)
{
    char A[255];
//  printf("请输入字符串:\n");
    gets(A);//输入字符数组
    String_Assign(S,A);//给字符串赋值
}//输入赋值

int String_Length(String S)
{
    return S.length;
}//返回字符串长度

void String_Show(String S)
{
    int i;
    for(i=0;i<S.length;i++)//逐个输出字符
        printf("%c",S.ch[i]);
    printf("\n");
}//出处字符串
/*
int String_Compare(String A,String B)
{
    int i;
    for(i=0;i<A.length&&i<B.length;i++)
        if(A.ch[i]!=B.ch[i])//两个对应位置字符不相同时
            break;
    return A.ch[i]-B.ch[i];//返回两者差值
}//字符串比较

void String_Clear(String &S) 
{
    if(S.ch)
    {
        free(S.ch);//释放空间
        S.ch=NULL;
    }
    S.length=0;
}//清空字符串
 */
void String_Contact(String &M,String S1,String S2)
{
    int i,j;
//  if(M.ch)
//      free(M.ch);
    M.ch=(char *)malloc((S1.length+S2.length)*sizeof(char));//申请新空间并判断是否成功
    if(!M.ch)
        exit(OVERFLOW);
    M.length=S1.length+S2.length;//初始化长度
    for(i=0;i<S1.length;i++)
        M.ch[i]=S1.ch[i];//把第一个字符串逐个复制
    for(j=0;j<S2.length;i++,j++)
        M.ch[i]=S2.ch[j];//逐个复制第二个字符串
}//字符串链接
/*
int String_Sub(String S,String &Sub,int Pos,int len)
{
    int i;
    if(Pos<0||Pos>S.length||len<0||Pos+len-1>S.length)//截取位置与长度是否合法
        return ERROR;
//  if(Sub.ch)
//      free(Sub.ch);
    if(len==0)//截取长度为0的情况
    {
        Sub.ch=NULL;
        Sub.length=0;
    }
    else
    {
        Sub.ch=(char *)malloc(len*sizeof(char));//申请空间并判断是否成功
        if(!Sub.ch)
            exit(OVERFLOW);
        Sub.length=len;//初始化长度
        for(i=0;i<Sub.length;i++,Pos++)//组个取值复制字符
            Sub.ch[i]=S.ch[Pos];
    }
    return OK;
}//截取子串

int String_Replace(String &S,String T,String V)
{
    int i,State;
    String Sub,Temp;
    for(i=0;i<S.length;i++)
    {
        State=String_Sub(S,Sub,i,T.length);//取相同长度子串
        if(State==ERROR)
            return ERROR;
        if(String_Compare(Sub,T)==0)//判断两者是否相等
            break;  
    }
    State=String_Sub(S,Temp,0,i);//将替换子串前的子串取出
    State=String_Sub(S,T,i+T.length,S.length-i-T.length);//将替换子串后的子串取出 
    String_Contact(Sub,Temp,V);//链接第一个子串和第二个子串
    String_Contact(S,Sub,T);//将前两个子串和最后一个子串链接
    return OK;
}//替换子串

int String_Delete(String &S,String T)
{
    int i,State,flag;
    String Sub,Temp;
    if(T.length==0)
        return ERROR;
    for(i=S.length-T.length;i>=0;i--)
    {
        State=String_Sub(S,Sub,i,T.length);//逐个取子串
        if(String_Compare(Sub,T)==0)//比较子串与目标串是否相等
        {
            flag=1;
            State=String_Sub(S,Sub,0,i);//取子串前一个子串
            State=String_Sub(S,Temp,i+T.length,S.length-i-T.length);//取子串后一个子串
            String_Contact(S,Sub,Temp);//链接两个子串
        }
    }
    if(flag==0)
        return ERROR;
    else
        return OK;      
}//删除子串

int String_BFmatch(String S,String T,int Pos[],int &N)
{
    int i,State;
    String Sub;
    N=0;
    Pos[0]=-1;
    for(i=0;i<=S.length-T.length;i++)
    {
        State=String_Sub(S,Sub,i,T.length);//逐个取子串
        if(State==ERROR)
            return ERROR;
        if(String_Compare(Sub,T)==0)//比较子串与目标串是否相等
            Pos[N++]=i;//存储位置
    }
    if(Pos[0]==-1)
        return ERROR;
    else
        return OK;
}//BF匹配算法
*/
void KMP_Next(String p,int next[])
{
    int j,k;
    next[0]=0;
    for(k=0,j=1;j<p.length;j++)
    {
        while(k>0&&p.ch[k]!=p.ch[j])
            k=next[k];//不等时递推寻找最长前缀
        if(p.ch[k]==p.ch[j])
            k++;//相等时,前缀直接加1
        next[j]=k;
    }
}//KMP算法跳转数组

int String_KMPmatch(String S,String T,int Pos[],int &N)
{
    int *next,i,j=0;
    next=(int *)malloc(T.length*sizeof(int));//申请空间构建next数组
    KMP_Next(T,next);
    N=0;
    Pos[0]=-1;
    for (i=0;i<S.length;i++) 
    {
        while (j>0&&S.ch[i]!=T.ch[j])//逐个比较模式串与主串
            j=next[j];//不匹配就跳转
        if(S.ch[i]==T.ch[j])
            j++;//匹配则移位
        if (j==T.length) 
        {
            Pos[N++]=i-j+1;//存储位置
            j=0;
        }
    }
    if(Pos[0]==-1)
        return ERROR;
    else
        return OK;
}//KMP算法
/*
void BM_Badc(String S,int BC[])
{
    int i;
    for(i=0;i<256;i++)//将所有字符都赋值为最大距离
        BC[i]=S.length;
    for(i=0;i<S.length;i++)//将模式串中的字符从新覆盖赋值为到串尾的距离
        BC[S.ch[i]]=S.length-i-1;
}//BM算法坏字符数组

void GoodS_Suffix(String S,int Suffix[])
{
    int i,j;
    Suffix[S.length-1]=S.length;
    for(i=S.length-2;i>=0;i--)
    {
        j=i;
        while(j>0&&S.ch[j]==S.ch[S.length-i-1+j])//求好后缀的长度
            j--;
        Suffix[i]=i-j;
    }
}//BM算法好后缀长度数组

void BM_Goods(String S,int GS[])
{
    int i,j,*Suffix;
    Suffix=(int *)malloc(S.length*sizeof(int));//申请好后缀长度数组
    if(!Suffix)
        exit(INFEASIBLE);
    GoodS_Suffix(S,Suffix);
    for(i=0;i<S.length;i++)//不存在匹配前缀则直接跳转模式串长度
        GS[i]=S.length;
    j=0;
    for(i=S.length-1;i>=0;i--)
        if(Suffix[i]==i+1)
            for (;j<S.length-1-i;j++)
                if (GS[j]==S.length)
                    GS[j]=S.length-1-i;//存在子串
    for (i=0;i<=S.length-2;i++)
            GS[S.length-1-Suffix[i]]=S.length-1-i;//存在相同的串
}//BM算法好后缀数组

int String_BMmatch(String S,String T,int Pos[],int &N)
{
    int i, j,*GS,*BC;
    BC=(int *)malloc(256*sizeof(int));
    if(!BC)
        exit(INFEASIBLE);
    GS=(int *)malloc(T.length*sizeof(int));
    if(!GS)
        exit(INFEASIBLE);
    BM_Badc(T,BC);
    BM_Goods(T,GS);//申请好后缀与坏字符空间
    j=0;
    N=0;
    Pos[0]=-1;
    while (j<=S.length-T.length) 
    {
        for (i=T.length-1;i>=0&&T.ch[i]==S.ch[i+j];i--);//从模式串尾部开始比较
        if (i<0) 
        {
            Pos[N++]=j;//存储位置
            j+=GS[0];//寻找下一个目标串
        }
        else
            j+=GS[i]>(BC[S.ch[i+j]]-T.length+1+i)?GS[i]:(BC[S.ch[i+j]]-T.length+1+i);//匹配失败时跳转最大长度
    }
    if(Pos[0]==-1)
        return ERROR;
    return OK;
}//BM算法
*/
void String_Read(String &S)
{
    FILE *fp;
    char str[1000];
    String Temp;
    fp=fopen("test.txt","r");//打开文件
    if(!fp)
        exit(INFEASIBLE);
    fgets(str,100,fp);
    String_Assign(S,str);//读取文件第一行并存储
    S.length--;//删除尾部换行符
    while(fgets(str,100,fp))
    {
        String_Assign(Temp,str);//逐个读取文件每行的字符串
        Temp.length--;//删除尾部换行符
        String_Contact(S,S,Temp);//链接
    }
    fclose(fp);
}//读取文件

int main()
{
    String S,T;
    int Pos[100],N,State,i;
    String_Read(S);
    String_Show(S);
    printf("\n请输入查找字符串:");
    String_Init(T);
/*  printf("----------B F算法----------\n");
    State=String_BFmatch(S,T,Pos,N);
    if(State==ERROR)
        printf("查找不到!\n\n");
    else
    {
        for(i=0;i<N;i++)
            printf("在位置%03d处发现目标字符串!\n",Pos[i]);
        printf("\n");
    }*/
    printf("----------KMP算法----------\n");
    State=String_KMPmatch(S,T,Pos,N);
    if(State==ERROR)
        printf("查找不到!\n\n");
    else
    {
        for(i=0;i<N;i++)
            printf("在位置%03d处发现目标字符串!\n",Pos[i]);
        printf("\n");
    }
/*  printf("----------B M算法----------\n");
    State=String_BMmatch(S,T,Pos,N);
    if(State==ERROR)
        printf("查找不到!\n\n");
    else
    {
        for(i=0;i<N;i++)
            printf("在位置%03d处发现目标字符串!\n",Pos[i]);
        printf("\n");
    }*/
    return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值