【算法和数据结构】_7_线性结构_字符串_模式匹配

  发现国内没有好的关于字符串处理的书籍,找了好久没有找到,不知道哪位大侠能介绍一本中文版的,英语的看的速度太慢。

下面是我测试的字符串模式匹配源代码

【Version 1】

    这个测试的时候,受北大那个视屏的影响,这个调试了老久没成功。最终虽然也能运行了,但是感觉怪怪的。

/*
    本程序测试字符串的各种处理函数和操作
*/


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


//******************************************************0
//            定义用户数据类型
typedef long int LINT;
typedef enum {FALSE,TRUE} BOOL;
//******************************************************1




//******************************************************0

LINT StringMatch(char* String,char* subString,LINT StartIndex);
LINT StringMatchRecall(char* String,char* subString,LINT StartIndex);
BOOL SubStringMatchHead(char* String,char* subString);
int GetMaxSubStringLen(const char* string);
LINT StringMatchKMP(const char* String,char* subString,LINT StartIndex);


int main(int argc,char* argv[])
{
    int x;

    x=StringMatch("abcdefghijabcdabmn","abcdab",0);
        printf("%d \n",x);

    x=StringMatchRecall("abcdefghijabcdabmn","mn",0);
        printf("%d \n",x);

    /*
    if(SubStringMatchHead("abcdefg","abc"))
        printf("%d \n",1);

    x=GetMaxSubStringLen("abcdefgabc");
        printf("%d \n",x);
   
    */
    getchar();
    getchar();
    return 0;
}
//******************************************************1





//******************************************************0
/*
函数功能:
    模式匹配朴素算法:双循环
函数原型:
    LINT StringMatch(char* String,char* subString,LINT StartIndex)
函数参数:
    char* String:字符串
    char* subString:模式字符串
    LINT StartIndex:搜索开始索引
返回值:
    如果匹配成功,则返回模式字符串在字符串中开始的首地址;
    如果匹配失败,则返回-1
异常:
    无
*/
LINT StringMatch(char* String,char* subString,LINT StartIndex)
{
    LINT i;
    int  j;
    LINT LastIndex;
    int  subStrLen;

    //检查指针有效性和空串
    //其实这里也可以不检测  StartIndex>strlen(String)-strlen(subString)
    if( !String || !subString || !String[0] || !subString\
        || StartIndex > strlen(String)-strlen(subString)\
      )
        return -1;

    LastIndex=strlen(String)-strlen(subString);
    subStrLen=strlen(subString);

    for(i=StartIndex;i<=LastIndex;i++)
    {
        for(j=0;j<subStrLen;j++)
        {
            if(String[i+j] - subString[j])
                break;
        }
        if(j==subStrLen)  //这么判断因为要结束循环正好相等
            return ++i;  //这个地方不能用i++
    }

    return -1;
}
//******************************************************1





//******************************************************0
/*
函数功能:
    模式匹配朴素算法:单循环回溯
函数原型:
    LINT StringMatchRecall(char* String,char* subString,LINT StartIndex)
函数参数:
    char* String:字符串
    char* subString:模式字符串
    LINT StartIndex:搜索开始索引
返回值:
    如果匹配成功,则返回模式字符串在字符串中开始的首地址;
    如果匹配失败,则返回-1
异常:
    无
*/
LINT StringMatchRecall(char* String,char* subString,LINT StartIndex)
{
    LINT i;
    LINT LastIndex;
    int  j;
    int  SubStrLen;
    int  StringLen;


    //检查指针有效性和空串
    //其实这里也可以不检测  StartIndex>strlen(String)-strlen(subString)
    if( !String || !subString || !String[0] || !subString\
        || StartIndex>strlen(String)-strlen(subString)\
      )  return -1;

    i=StartIndex;
    j=0;

    SubStrLen=strlen(subString);
    StringLen=strlen(String);
    LastIndex=strlen(String) - SubStrLen ;
    

    while( i<=StringLen  && j<=SubStrLen)
    {    
        if(String[i] == subString[j] )
        {
            if(j==SubStrLen-1)
                return i-j+1;
            ++i;
            ++j;
        }
        else
        {
            
            i=i-j+1;  //回溯  
            j=0;
        }
    }
        return -1;
}
//******************************************************1

   

    下面是后来调试的源代码,经过测试能得到正确的结果。

 /*
    本程序测试字符串的各种处理函数和操作
*/


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


//******************************************************0
//            定义用户数据类型
typedef long int LINT;
typedef enum {FALSE,TRUE} BOOL;
//******************************************************1




//******************************************************0

int StringMatch(char* String,char* subString,int StartIndex);
int StringMatchRecall(char* String,char* subString,int StartIndex);
BOOL  StrMatch(char* string,char* subStr,int len);
//BOOL  GetStrNextJ(char* string,int* nextJ);

int main(int argc,char* argv[])
{
    int x;
    int i;
    int arrayNum[100]={0};

 

    x=StringMatch("abcdefghijklmn","lm",0);
        printf("%d \n",x);

    x=StringMatchRecall("abcdefghijklmn","x",0);
        printf("%d \n",x);


    if(StrMatch("abcdefg","bc",strlen("bc")))
        printf("Match");
    else
        printf("Not match");
    putchar(13);

    getchar();
    getchar();
    return 0;
}
//******************************************************1





//******************************************************0
/*
函数功能:
    模式匹配朴素算法:双循环
函数原型:
    int StringMatch(char* String,char* subString,int StartIndex)
函数参数:
    char* String:字符串
    char* subString:模式字符串
    int StartIndex:搜索开始索引
返回值:
    如果匹配成功,则返回模式字符串在字符串中开始的首地址;
    如果匹配失败,则返回-1
异常:
    无
*/
int StringMatch(char* String,char* subString,int StartIndex)
{
    int i,
        j;

    int StrLen,
        SubStrLen;

    StrLen=strlen(String);
    SubStrLen=strlen(subString);

    //检查指针有效性和空串
    //其实这里也可以不检测  StartIndex>strlen(String)-strlen(subString)
    if( !String || !subString || !String[0] || !subString\
        || StartIndex > StrLen-SubStrLen\
      )
        return -1;

    for(i=StartIndex;i<= StrLen - SubStrLen ;i++)
    {
        for(j=0; j < SubStrLen ;j++)
        {
            if(String[i+j] - subString[j])
                break;
        }
        if(j==SubStrLen)  //这么判断因为要结束循环正好相等
            return ++i;  //这个地方不能用i++
    }

    return -1;
}
//******************************************************1





//******************************************************0
/*
函数功能:
    模式匹配朴素算法:单循环回溯
函数原型:
    int StringMatchRecall(char* String,char* subString,LINT StartIndex)
函数参数:
    char* String:字符串
    char* subString:模式字符串
    int StartIndex:搜索开始索引
返回值:
    如果匹配成功,则返回模式字符串在字符串中开始的首地址;
    如果匹配失败,则返回-1
异常:
    无
*/
int StringMatchRecall(char* String,char* subString,int StartIndex)
{
    int i,
        j;

    int StrLen,
        SubStrLen;

    StrLen=strlen(String);
    SubStrLen=strlen(subString);

    //检查指针有效性和空串
    //其实这里也可以不检测  StartIndex>strlen(String)-strlen(subString)
    if( !String || !subString || !String[0] || !subString\
        || StartIndex > StrLen-SubStrLen\
      )  return -1;

    i=StartIndex;
    j=0;

    while( i < StrLen  )
    {
        if(String[i] == subString[j] )
        {
            ++j;
            ++i;
             
        }
        else
        {
            i=i-j+1;  //回溯
            j=0;
        }
        if(j==SubStrLen)
            return i-j+1;
    }
    return -1;
}
//******************************************************1






//******************************************************0
/*
函数功能:
    判断字符串String和subStr是否相等; 相当于strcmp函数,
    但是这个函数需要传递3个参数
函数原型:
    BOOL  StrMatch(char* string,char* subStr,int len)
函数参数:
    char* string:字符串1
    char* subStr:字符串2,字符串string的子串
    int len:字符串2的长度
返回值:
    如果匹配成功则返回TRUE,否则返回FALSE;
异常:
    无
*/
BOOL  StrMatch(char* string,char* subStr,int len)
{
    int i;

    if(!string || !subStr || strlen(string)<=len)
        return FALSE;

    i=0;
    while(i<len)
    {
        if(string[i] != subStr[i])
            return FALSE;  //比较过程中,如果出现不匹配现象就返回

        i++; //如果相等就继续比较
    }

    return  TRUE;
}
//******************************************************1

  这里原本要调试KMP算法的,但是调试了很久都没有成功,主要是自己还没有完全理解KMP算法的思路,只能等到以后慢慢替换了。

看来园子里部分大侠的代码和分析,还是不甚理解KMP算法。

原文地址:https://www.cnblogs.com/volcanol/p/3043573.html