串的基本操作(含KMP算法及KMP优化算法)

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

#define MaxSize 50

typedef struct{
    char ch[MaxSize];
    int length=0;
}SString;

int StrAssign(SString &T,char *m){
    int i=1;
    while(m[i-1]!='\0'){
        T.length=i;
        if(i>MaxSize){
            printf("FULL\n");
            T.length=0;
            return 0;
        }
        T.ch[i]=m[i-1];
        i++;
    }
    return 1;
}

int StrCopy(SString &T,SString S){
    int i;
    for(i=1;i<=S.length;i++){
        T.ch[i]=S.ch[i];
    }
    T.length=S.length;
    return 1;
}

int StrCompare(SString T,SString S){
    for(int i=1;i<=T.length&&i<=S.length;i++){
        if(T.ch[i]!=S.ch[i])
            return T.ch[i]-S.ch[i];
    }
    return T.length-S.length;
}

int StrLength(SString T){
    printf("The length is %d\n",T.length);
    return 1;
}

int PrintfStr(SString T){
    if(T.length==0)
        printf("The String is Empty\n");
    else{
        for(int i=1;i<=T.length;i++)
            printf("%c",T.ch[i]);
    }
    printf("\n");
    return 1;
}

int Concat(SString &T,SString S1,SString S2){
    int i;
    T.length=S1.length+S2.length;
    if(T.length>MaxSize){
        T.length=0;
        printf("FULL\n");
        return 0;
    }
    for(i=1;i<=S1.length;i++){
        T.ch[i]=S1.ch[i];
    }
    for(i=1;i<=S2.length;i++){
        T.ch[i+S1.length]=S2.ch[i];
    }
    return 1;
}

int SubString(SString &Sub,SString S,int pos,int len){
    if(pos<0||pos>S.length){
        printf("Pos ERROR\n");
        return 0;
    }
    if(len<0||pos+len-1>S.length){
        printf("Len ERROR\n");
        return 0;
    }
    if(len==0)
        Sub.length=0;
    else{
        for(int i=1;i<=len;i++){
            Sub.ch[i]=S.ch[pos+i-1];
        }
        Sub.length=len;
    }
    return 1;
}

int StrInsert(SString &T,int pos,SString S){
    if(pos<0||pos>T.length+1){
        printf("Pos ERROE\n");
        return 0;
    }
    if(T.length+S.length>MaxSize){
        printf("FULL\n");
        return 0;
    }
    for(int i=1;i<=T.length-pos+1;i++){
        T.ch[T.length+S.length+1-i]=T.ch[T.length+1-i];
    }
    for(int i=pos;i<=pos+S.length-1;i++){
        T.ch[i]=S.ch[i-pos+1];
    }
    T.length+=S.length;
    return 1;
}

int StrDelete(SString &T,int pos,int len){
    if(pos<0||pos>T.length){
        printf("Pos ERROE\n");
        return 0;
    }
    if(len<0||pos+len-1>T.length){
        printf("Len Error\n");
        return 0;
    }
    for(int i=pos;i<=T.length-len;i++){
        T.ch[i]=T.ch[i+len];
    }
    T.length-=len;
    return 1;
}

int get_next(SString T,int next[]){			//求KMP算法的next数组
    int i=1,j=0;
    next[1]=0;
    while(i<T.length){
        if(j==0||T.ch[i]==T.ch[j]){
            ++i;    ++j;
            next[i]=j;
        }
        else    j=next[j];
    }
    return 1;
}

int get_nextval(SString T,int nextval[]){	//求KMP优化算法的nextval数组
    int i=1,j=0;
    nextval[1]=0;
    while(i<T.length){
        if(j==0||T.ch[i]==T.ch[j]){
            ++i;    ++j;
            if(T.ch[i]!=T.ch[j])    nextval[i]=j;
            else    nextval[i]=nextval[j];
        }
        else    j=nextval[j];
    }
    return 1;
}

int Index(SString S,SString T,int pos){		//朴素算法
    if(pos>0){
        int n=S.length,m=T.length,i=pos;
        SString Sub;
        while(i<=n-m+1){
            SubString(Sub, S, i, m);
            if(StrCompare(Sub, T)!=0) ++i;
            else return i;
        }
    }
    return 0;
}

int Index_KMP(SString S,SString T,int pos){		//KMP算法
    int i=pos,j=1;
    int next[MaxSize];
    get_next(T, next);
    while(i<=S.length&&j<=T.length){
        if(j==0 || S.ch[i]==T.ch[j]){    ++i;    ++j;}
        else    j=next[j];
    }
    if(j>T.length)  return i-T.length;
    else return 0;
}

int Index_KMP_optimize(SString S,SString T,int pos){		//KMP优化算法
    int i=pos,j=1;
    int nextval[MaxSize];
    get_nextval(T, nextval);
    while(i<=S.length&&j<=T.length){
        if(j==0 || S.ch[i]==T.ch[j]){    ++i;    ++j;}
        else    j=nextval[j];
    }
    if(j>T.length)  return i-T.length;
    else return 0;
}

int Replace(SString &T,SString S,SString V){
    int pos;
    while((pos=Index(T, S, 1))){
        StrDelete(T, pos, S.length);
        StrInsert(T, pos, V);
    }
    return 1;
}

int DestoryString(SString &T){
    free(T.ch);
    T.length=0;
    return 1;
}

int main() {			//测试代码,随意更改
    char m[100];
    SString T,S;
    scanf("%s",m);
    StrAssign(T, m);
    scanf("%s",m);
    StrAssign(S, m);
    printf("%d\n",Index(T, S, 1));
    printf("%d\n",Index_KMP(T, S, 1));
    printf("%d\n",Index_KMP_optimize(T, S, 1));
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_46200758/article/details/108548099