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

  其实,模式匹配的穷举法也可以改进,下面是经过改进后的代码。

【Improve Version】

  其中StrMatchImp()函数是经过改进后的函数。

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


#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);
int  StrMatchImp(char* string,char* subString,int startIndex);

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

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

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

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

    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
/*
函数功能:
    字符串模式匹配穷举法:改进版
函数原型:
    int  StrMatchImp(char* string,char* subString,int startIndex)
函数参数:
    char* string: 字符串
    char* subString:模式字符串
    int startIndex:搜索首索引
返回值:
    如果匹配成功,返回匹配首字符的index+1
异常:
    无
*/
int  StrMatchImp(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;
            else
            {   
                //如果模式的首字符subString[0]已经匹配,
                //则判断最后一个字符subString[SubStrLen-1]是否匹配
                //依次类推,这样最好的时候可以提高效率,
                //最差的时候还是需要O(m*n) 
                if(string[i+SubStrLen-1-j] - subString[SubStrLen-1-j])
                    break;
            }
        }
        if(j==SubStrLen)  //这么判断因为要结束循环正好相等,也可用subString[j]=='\0'
            return ++i;  //这个地方不能用i++
    }

    return -1;
}

//******************************************************1















//******************************************************0
/*
函数功能:
    求解字符串本身的从尾节点往头节点方向子串中最大的匹配串
函数原型:
    int GetMaxSubStringLen(const char* string)
函数参数:
    const char* String:字符串
返回值:
    如果有的话则返回最大长度,否则就返回-1
异常:
    无
*/
int GetMaxSubStringLen(const char* string)
{
    return -1;
}
//******************************************************1

  程序运行结果如下所示:

  

  这个东西还是有很复杂啊,哎,需要继续学习学习。

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